src/eric7/Utilities/ClassBrowsers/__init__.py

Thu, 07 Jul 2022 11:23:56 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 07 Jul 2022 11:23:56 +0200
branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
eric7/Utilities/ClassBrowsers/__init__.py@54e42bc2437a
child 9221
bf71ee032bb4
permissions
-rw-r--r--

Reorganized the project structure to use the source layout in order to support up-to-date build systems with "pyproject.toml".

# -*- coding: utf-8 -*-

# Copyright (c) 2005 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Package implementing class browsers for various languages.

Currently it offers class browser support for the following
programming languages.

<ul>
<li>CORBA IDL</li>
<li>JavaScript</li>
<li>ProtoBuf</li>
<li>Python 3</li>
<li>Ruby</li>
</ul>
"""

import os
import importlib

import Preferences

PY_SOURCE = 1
PTL_SOURCE = 128
RB_SOURCE = 129
IDL_SOURCE = 130
JS_SOURCE = 131
PROTO_SOURCE = 132

SUPPORTED_TYPES = [PY_SOURCE, PTL_SOURCE, RB_SOURCE, IDL_SOURCE, JS_SOURCE,
                   PROTO_SOURCE]

__extensions = {
    "IDL": [".idl"],
    "Python": [".py", ".pyw", ".ptl"],  # currently not used
    "Ruby": [".rb"],
    "JavaScript": [".js"],
    "ProtoBuf": [".proto"],
}


def readmodule(module, path=None, isPyFile=False):
    """
    Read a source file and return a dictionary of classes, functions, modules,
    etc. .
    
    The real work of parsing the source file is delegated to the individual
    file parsers.

    @param module name of the source file
    @type str
    @param path list of paths the file should be searched in
    @type list of str
    @param isPyFile flag indicating a Python file
    @type bool
    @return the resulting dictionary
    @rtype dict
    """
    ext = os.path.splitext(module)[1].lower()
    path = [] if path is None else path[:]
    
    if ext in __extensions["IDL"]:
        from . import idlclbr
        dictionary = idlclbr.readmodule_ex(module, path)
        idlclbr._modules.clear()
    elif ext in __extensions["ProtoBuf"]:
        from . import protoclbr
        dictionary = protoclbr.readmodule_ex(module, path)
        protoclbr._modules.clear()
    elif ext in __extensions["Ruby"]:
        from . import rbclbr
        dictionary = rbclbr.readmodule_ex(module, path)
        rbclbr._modules.clear()
    elif ext in __extensions["JavaScript"]:
        from . import jsclbr
        dictionary = jsclbr.readmodule_ex(module, path)
        jsclbr._modules.clear()
    elif (
        ext in Preferences.getPython("Python3Extensions") or
        isPyFile
    ):
        from . import pyclbr
        dictionary = pyclbr.readmodule_ex(module, path, isPyFile=isPyFile)
        pyclbr._modules.clear()
    else:
        # try Python if it is without extension
        from . import pyclbr
        dictionary = pyclbr.readmodule_ex(module, path)
        pyclbr._modules.clear()
    
    return dictionary


def find_module(name, path, isPyFile=False):
    """
    Module function to extend the Python module finding mechanism.
    
    This function searches for files in the given list of paths. If the
    file name doesn't have an extension or an extension of .py, the normal
    Python search implemented in the imp module is used. For all other
    supported files only the paths list is searched.
    
    @param name file name or module name to search for
    @type str
    @param path search paths
    @type list of str
    @param isPyFile flag indicating a Python file
    @type bool
    @return tuple of the open file, pathname and description. Description
        is a tuple of file suffix, file mode and file type)
    @rtype tuple
    @exception ImportError The file or module wasn't found.
    """
    ext = os.path.splitext(name)[1].lower()
    
    if ext in __extensions["Ruby"]:
        for p in path:      # only search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', RB_SOURCE))
                # __IGNORE_WARNING_Y115__
        raise ImportError
    
    elif ext in __extensions["IDL"]:
        for p in path:      # only search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', IDL_SOURCE))
                # __IGNORE_WARNING_Y115__
        raise ImportError
    
    elif ext in __extensions["ProtoBuf"]:
        for p in path:      # only search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', PROTO_SOURCE))
                # __IGNORE_WARNING_Y115__
        raise ImportError
    
    elif ext in __extensions["JavaScript"]:
        for p in path:      # only search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', JS_SOURCE))
                # __IGNORE_WARNING_Y115__
        raise ImportError
    
    elif ext == '.ptl':
        for p in path:      # only search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', PTL_SOURCE))
                # __IGNORE_WARNING_Y115__
        raise ImportError
    
    elif (
        name.lower().endswith(
            tuple(Preferences.getPython("Python3Extensions"))) or
        isPyFile
    ):
        for p in path:      # search in path
            pathname = os.path.join(p, name)
            if os.path.exists(pathname):
                return (open(pathname), pathname, (ext, 'r', PY_SOURCE))
                # __IGNORE_WARNING_Y115__
    raise ImportError
    
    # standard Python module file
    if name.lower().endswith('.py'):
        name = name[:-3]
    
    spec = importlib.machinery.PathFinder.find_spec(name, path)
    if spec is None:
        raise ImportError
    if isinstance(spec.loader, importlib.machinery.SourceFileLoader):
        ext = os.path.splitext(spec.origin)[-1]
        return (open(spec.origin), spec.origin, (ext, 'r', PY_SOURCE))
        # __IGNORE_WARNING_Y115__
    
    raise ImportError

eric ide

mercurial