1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Package implementing class browsers for various languages. 8 9Currently it offers class browser support for the following 10programming languages. 11 12<ul> 13<li>CORBA IDL</li> 14<li>JavaScript</li> 15<li>ProtoBuf</li> 16<li>Python 3</li> 17<li>Ruby</li> 18</ul> 19""" 20 21import os 22import importlib 23 24import Preferences 25 26PY_SOURCE = 1 27PTL_SOURCE = 128 28RB_SOURCE = 129 29IDL_SOURCE = 130 30JS_SOURCE = 131 31PROTO_SOURCE = 132 32 33SUPPORTED_TYPES = [PY_SOURCE, PTL_SOURCE, RB_SOURCE, IDL_SOURCE, JS_SOURCE, 34 PROTO_SOURCE] 35 36__extensions = { 37 "IDL": [".idl"], 38 "Python": [".py", ".pyw", ".ptl"], # currently not used 39 "Ruby": [".rb"], 40 "JavaScript": [".js"], 41 "ProtoBuf": [".proto"], 42} 43 44 45def readmodule(module, path=None, isPyFile=False): 46 """ 47 Read a source file and return a dictionary of classes, functions, modules, 48 etc. . 49 50 The real work of parsing the source file is delegated to the individual 51 file parsers. 52 53 @param module name of the source file 54 @type str 55 @param path list of paths the file should be searched in 56 @type list of str 57 @param isPyFile flag indicating a Python file 58 @type bool 59 @return the resulting dictionary 60 @rtype dict 61 """ 62 ext = os.path.splitext(module)[1].lower() 63 path = [] if path is None else path[:] 64 65 if ext in __extensions["IDL"]: 66 from . import idlclbr 67 dictionary = idlclbr.readmodule_ex(module, path) 68 idlclbr._modules.clear() 69 elif ext in __extensions["ProtoBuf"]: 70 from . import protoclbr 71 dictionary = protoclbr.readmodule_ex(module, path) 72 protoclbr._modules.clear() 73 elif ext in __extensions["Ruby"]: 74 from . import rbclbr 75 dictionary = rbclbr.readmodule_ex(module, path) 76 rbclbr._modules.clear() 77 elif ext in __extensions["JavaScript"]: 78 from . import jsclbr 79 dictionary = jsclbr.readmodule_ex(module, path) 80 jsclbr._modules.clear() 81 elif ( 82 ext in Preferences.getPython("Python3Extensions") or 83 isPyFile 84 ): 85 from . import pyclbr 86 dictionary = pyclbr.readmodule_ex(module, path, isPyFile=isPyFile) 87 pyclbr._modules.clear() 88 else: 89 # try Python if it is without extension 90 from . import pyclbr 91 dictionary = pyclbr.readmodule_ex(module, path) 92 pyclbr._modules.clear() 93 94 return dictionary 95 96 97def find_module(name, path, isPyFile=False): 98 """ 99 Module function to extend the Python module finding mechanism. 100 101 This function searches for files in the given list of paths. If the 102 file name doesn't have an extension or an extension of .py, the normal 103 Python search implemented in the imp module is used. For all other 104 supported files only the paths list is searched. 105 106 @param name file name or module name to search for 107 @type str 108 @param path search paths 109 @type list of str 110 @param isPyFile flag indicating a Python file 111 @type bool 112 @return tuple of the open file, pathname and description. Description 113 is a tuple of file suffix, file mode and file type) 114 @rtype tuple 115 @exception ImportError The file or module wasn't found. 116 """ 117 ext = os.path.splitext(name)[1].lower() 118 119 if ext in __extensions["Ruby"]: 120 for p in path: # only search in path 121 pathname = os.path.join(p, name) 122 if os.path.exists(pathname): 123 return (open(pathname), pathname, (ext, 'r', RB_SOURCE)) 124 # __IGNORE_WARNING_Y115__ 125 raise ImportError 126 127 elif ext in __extensions["IDL"]: 128 for p in path: # only search in path 129 pathname = os.path.join(p, name) 130 if os.path.exists(pathname): 131 return (open(pathname), pathname, (ext, 'r', IDL_SOURCE)) 132 # __IGNORE_WARNING_Y115__ 133 raise ImportError 134 135 elif ext in __extensions["ProtoBuf"]: 136 for p in path: # only search in path 137 pathname = os.path.join(p, name) 138 if os.path.exists(pathname): 139 return (open(pathname), pathname, (ext, 'r', PROTO_SOURCE)) 140 # __IGNORE_WARNING_Y115__ 141 raise ImportError 142 143 elif ext in __extensions["JavaScript"]: 144 for p in path: # only search in path 145 pathname = os.path.join(p, name) 146 if os.path.exists(pathname): 147 return (open(pathname), pathname, (ext, 'r', JS_SOURCE)) 148 # __IGNORE_WARNING_Y115__ 149 raise ImportError 150 151 elif ext == '.ptl': 152 for p in path: # only search in path 153 pathname = os.path.join(p, name) 154 if os.path.exists(pathname): 155 return (open(pathname), pathname, (ext, 'r', PTL_SOURCE)) 156 # __IGNORE_WARNING_Y115__ 157 raise ImportError 158 159 elif ( 160 name.lower().endswith( 161 tuple(Preferences.getPython("Python3Extensions"))) or 162 isPyFile 163 ): 164 for p in path: # search in path 165 pathname = os.path.join(p, name) 166 if os.path.exists(pathname): 167 return (open(pathname), pathname, (ext, 'r', PY_SOURCE)) 168 # __IGNORE_WARNING_Y115__ 169 raise ImportError 170 171 # standard Python module file 172 if name.lower().endswith('.py'): 173 name = name[:-3] 174 175 spec = importlib.machinery.PathFinder.find_spec(name, path) 176 if spec is None: 177 raise ImportError 178 if isinstance(spec.loader, importlib.machinery.SourceFileLoader): 179 ext = os.path.splitext(spec.origin)[-1] 180 return (open(spec.origin), spec.origin, (ext, 'r', PY_SOURCE)) 181 # __IGNORE_WARNING_Y115__ 182 183 raise ImportError 184