Tue, 08 Nov 2022 18:03:11 +0100
Changed class browser imports to use importlib.import_module().
--- a/src/eric7/Utilities/ClassBrowsers/__init__.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/__init__.py Tue Nov 08 18:03:11 2022 +0100 @@ -29,6 +29,7 @@ IDL_SOURCE = 130 JS_SOURCE = 131 PROTO_SOURCE = 132 +UNKNOWN_SOURCE = 255 SUPPORTED_TYPES = [ PY_SOURCE, @@ -48,10 +49,36 @@ } +def getClassBrowserModule(moduleType): + """ + Function to import a class browser module. + + @param moduleType type of class browser to load + @type str + @return reference to the imported class browser module + @rtype module + """ + typeMapping = { + "idl": "idlclbr", + "javascript": "jsclbr", + "protobuf": "protoclbr", + "python": "pyclbr", + "ruby": "rbclbr", + } + + if moduleType in typeMapping: + mod = importlib.import_module( + "eric7.Utilities.ClassBrowsers.{0}".format(typeMapping[moduleType]) + ) + return mod + + return None + + def readmodule(module, path=None, isPyFile=False): """ - Read a source file and return a dictionary of classes, functions, modules, - etc. . + Function to 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. @@ -69,43 +96,32 @@ path = [] if path is None else path[:] if ext in __extensions["IDL"]: - from . import idlclbr # __IGNORE_WARNING_I101__ - - dictionary = idlclbr.readmodule_ex(module, path) - idlclbr._modules.clear() + moduleType = "idl" elif ext in __extensions["ProtoBuf"]: - from . import protoclbr # __IGNORE_WARNING_I101__ - - dictionary = protoclbr.readmodule_ex(module, path) - protoclbr._modules.clear() + moduleType = "protobuf" elif ext in __extensions["Ruby"]: - from . import rbclbr # __IGNORE_WARNING_I101__ - - dictionary = rbclbr.readmodule_ex(module, path) - rbclbr._modules.clear() + moduleType = "ruby" elif ext in __extensions["JavaScript"]: - from . import jsclbr # __IGNORE_WARNING_I101__ - - dictionary = jsclbr.readmodule_ex(module, path) - jsclbr._modules.clear() + moduleType = "javascript" elif ext in Preferences.getPython("Python3Extensions") or isPyFile: - from . import pyclbr # __IGNORE_WARNING_I101__ - - dictionary = pyclbr.readmodule_ex(module, path, isPyFile=isPyFile) - pyclbr._modules.clear() + moduleType = "python" else: # try Python if it is without extension - from . import pyclbr # __IGNORE_WARNING_I101__ + moduleType = "python" - dictionary = pyclbr.readmodule_ex(module, path) - pyclbr._modules.clear() + classBrowserModule = getClassBrowserModule(moduleType) + if classBrowserModule: + dictionary = classBrowserModule.readmodule_ex(module, path, isTypeFile=isPyFile) + classBrowserModule.clearModulesCache() + else: + dictionary = {} return dictionary def find_module(name, path, isPyFile=False): """ - Module function to extend the Python module finding mechanism. + 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 @@ -126,66 +142,41 @@ 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 - + sourceType = RB_SOURCE 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 - + sourceType = IDL_SOURCE 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 - + sourceType = PROTO_SOURCE 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 - + sourceType = JS_SOURCE 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 - + sourceType = PTL_SOURCE elif ( name.lower().endswith(tuple(Preferences.getPython("Python3Extensions"))) or isPyFile ): + sourceType = PY_SOURCE + else: + sourceType = UNKNOWN_SOURCE + + if sourceType != UNKNOWN_SOURCE: 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)) + return (open(pathname), pathname, (ext, "r", sourceType)) # __IGNORE_WARNING_Y115__ - raise ImportError - - # standard Python module file - if name.lower().endswith(".py"): - name = name[:-3] + raise ImportError + else: + # 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__ + 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
--- a/src/eric7/Utilities/ClassBrowsers/idlclbr.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/idlclbr.py Tue Nov 08 18:03:11 2022 +0100 @@ -95,6 +95,13 @@ _modules = {} # cache of modules we've seen +def clearModulesCache(): + """ + Function to clear the cached modules. + """ + _modules.clear() + + class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. @@ -204,15 +211,17 @@ VisibilityMixin.__init__(self) -def readmodule_ex(module, path=None): +def readmodule_ex(module, path=None, isTypeFile=False): """ Read a CORBA IDL file and return a dictionary of classes, functions and modules. - @param module name of the CORBA IDL file + @param module name of the IDL file @type str @param path path the file should be searched in @type list of str + @param isTypeFile flag indicating a file of this type + @type bool @return the resulting dictionary @rtype dict """
--- a/src/eric7/Utilities/ClassBrowsers/jsclbr.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/jsclbr.py Tue Nov 08 18:03:11 2022 +0100 @@ -22,6 +22,13 @@ _modules = {} # cache of modules we've seen +def clearModulesCache(): + """ + Function to clear the cached modules. + """ + _modules.clear() + + class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. @@ -286,13 +293,18 @@ ) -def readmodule_ex(module, path=None): +def readmodule_ex(module, path=None, isTypeFile=False): """ Read a JavaScript file and return a dictionary of functions and variables. - @param module name of the JavaScript file (string) - @param path path the file should be searched in (list of strings) + @param module name of the JavaScript file + @type str + @param path path the file should be searched in + @type list of str + @param isTypeFile flag indicating a file of this type + @type bool @return the resulting dictionary + @rtype dict """ global _modules
--- a/src/eric7/Utilities/ClassBrowsers/protoclbr.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/protoclbr.py Tue Nov 08 18:03:11 2022 +0100 @@ -91,6 +91,13 @@ _modules = {} # cache of modules we've seen +def clearModulesCache(): + """ + Function to clear the cached modules. + """ + _modules.clear() + + class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. @@ -201,7 +208,7 @@ VisibilityMixin.__init__(self) -def readmodule_ex(module, path=None): +def readmodule_ex(module, path=None, isTypeFile=False): """ Read a ProtoBuf protocol file and return a dictionary of messages, enums, services and rpc methods. @@ -210,6 +217,8 @@ @type str @param path path the file should be searched in @type list of str + @param isTypeFile flag indicating a file of this type + @type bool @return the resulting dictionary @rtype dict """
--- a/src/eric7/Utilities/ClassBrowsers/pyclbr.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/pyclbr.py Tue Nov 08 18:03:11 2022 +0100 @@ -142,6 +142,13 @@ _modules = {} # cache of modules we've seen +def clearModulesCache(): + """ + Function to clear the cached modules. + """ + _modules.clear() + + class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. @@ -354,7 +361,7 @@ self.importedNames[name].append(lineno) -def readmodule_ex(module, path=None, inpackage=False, isPyFile=False): +def readmodule_ex(module, path=None, isTypeFile=False): """ Read a module file and return a dictionary of classes. @@ -366,9 +373,7 @@ @type str @param path path the module should be searched in @type list of str - @param inpackage flag indicating a module inside a package is scanned - @type bool - @param isPyFile flag indicating a Python file + @param isTypeFile flag indicating a file of this type @type bool @return the resulting dictionary @rtype dict @@ -386,15 +391,10 @@ # search the path for the module path = [] if path is None else path[:] f = None - if inpackage: - try: - f, file, (suff, mode, type) = ClassBrowsers.find_module(module, path) - except ImportError: - f = None if f is None: fullpath = path[:] + sys.path[:] f, file, (suff, mode, type) = ClassBrowsers.find_module( - module, fullpath, isPyFile + module, fullpath, isTypeFile ) if f: f.close()
--- a/src/eric7/Utilities/ClassBrowsers/rbclbr.py Tue Nov 08 16:57:46 2022 +0100 +++ b/src/eric7/Utilities/ClassBrowsers/rbclbr.py Tue Nov 08 18:03:11 2022 +0100 @@ -165,6 +165,13 @@ _modules = {} # cache of modules we've seen +def clearModulesCache(): + """ + Function to clear the cached modules. + """ + _modules.clear() + + class VisibilityMixin(ClbrBaseClasses.ClbrVisibilityMixinBase): """ Mixin class implementing the notion of visibility. @@ -255,13 +262,18 @@ self.setPrivate() -def readmodule_ex(module, path=None): +def readmodule_ex(module, path=None, isTypeFile=False): """ Read a Ruby file and return a dictionary of classes, functions and modules. - @param module name of the Ruby file (string) - @param path path the file should be searched in (list of strings) + @param module name of the Ruby file + @type str + @param path path the file should be searched in + @type list of str + @param isTypeFile flag indicating a file of this type + @type bool @return the resulting dictionary + @rtype dict """ global _modules