Utilities/ClassBrowsers/pyclbr.py

changeset 4183
856ba07de877
parent 4021
195a471c327b
child 4435
9f6555d3c3c0
diff -r a84cadf71513 -r 856ba07de877 Utilities/ClassBrowsers/pyclbr.py
--- a/Utilities/ClassBrowsers/pyclbr.py	Tue Mar 24 19:40:12 2015 +0100
+++ b/Utilities/ClassBrowsers/pyclbr.py	Wed Mar 25 20:01:08 2015 +0100
@@ -105,6 +105,27 @@
         (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : (?= \s* def)
     )
 
+|   (?P<Import>
+        ^ [ \t]* (?: import | from [ \t]+ \. [ \t]+ import ) [ \t]+
+        (?P<ImportList> (?: [^#;\\\n]* (?: \\\n )* )* )
+    )
+
+|   (?P<ImportFrom>
+        ^ [ \t]* from [ \t]+
+        (?P<ImportFromPath>
+            \.* \w+
+            (?:
+                [ \t]* \. [ \t]* \w+
+            )*
+        )
+        [ \t]+
+        import [ \t]+
+        (?P<ImportFromList>
+            (?: \( \s* .*? \s* \) )
+            |
+            (?: [^#;\\\n]* (?: \\\n )* )* )
+    )
+
 |   (?P<CodingLine>
         ^ \# \s* [*_-]* \s* coding[:=] \s* (?P<Coding> [-\w_.]+ ) \s* [*_-]* $
     )
@@ -209,6 +230,97 @@
         self.lineno = lineno
         self.identifiers = [e.replace('"', '').replace("'", "").strip()
                             for e in idents.split(',')]
+
+
+class Imports(object):
+    """
+    Class to represent the list of imported modules.
+    """
+    def __init__(self, module, file):
+        """
+        Constructor
+        
+        @param module name of the module containing the import (string)
+        @param file file name containing the import (string)
+        """
+        self.module = module
+        self.name = 'import'
+        self.file = file
+        self.imports = {}
+    
+    def addImport(self, moduleName, names, lineno):
+        """
+        Public method to add a list of imported names.
+        
+        @param moduleName name of the imported module (string)
+        @param names list of names (list of strings)
+        @param lineno line number of the import
+        """
+        if moduleName not in self.imports:
+            module = ImportedModule(self.module, self.file, moduleName)
+            self.imports[moduleName] = module
+        else:
+            module = self.imports[moduleName]
+        module.addImport(lineno, names)
+    
+    def getImport(self, moduleName):
+        """
+        Public method to get an imported module item.
+        
+        @param moduleName name of the imported module (string)
+        @return imported module item (ImportedModule) or None
+        """
+        if moduleName in self.imports:
+            return self.imports[moduleName]
+        else:
+            return None
+    
+    def getImports(self):
+        """
+        Public method to get all imported module names.
+        
+        @return dictionary of imported module names with name as key and list
+            of line numbers of imports as value
+        """
+        return self.imports
+
+
+class ImportedModule(object):
+    """
+    Class to represent an imported module.
+    """
+    def __init__(self, module, file, importedModule):
+        """
+        Constructor
+        
+        @param module name of the module containing the import (string)
+        @param file file name containing the import (string)
+        @param importedModule name of the imported module (string)
+        """
+        self.module = module
+        self.name = 'import'
+        self.file = file
+        self.importedModuleName = importedModule
+        self.linenos = []
+        self.importedNames = {}
+        # dictionary of imported names with name as key and list of line
+        # numbers as value
+    
+    def addImport(self, lineno, importedNames):
+        """
+        Public method to add a list of imported names.
+        
+        @param lineno line number of the import
+        @param importedNames list of imported names (list of strings)
+        """
+        if lineno not in self.linenos:
+            self.linenos.append(lineno)
+        
+        for name in importedNames:
+            if name not in self.importedNames:
+                self.importedNames[name] = [lineno]
+            else:
+                self.importedNames[name].append(lineno)
     
 
 def readmodule_ex(module, path=[], inpackage=False, isPyFile=False):
@@ -480,6 +592,36 @@
             pubs = Publics(module, file, lineno, idents)
             dict['__all__'] = pubs
         
+        elif m.start("Import") >= 0:
+            # import module
+            names = [n.strip() for n in
+                     "".join(m.group("ImportList").splitlines())
+                     .replace("\\", "").split(',')]
+            lineno = lineno + src.count('\n', last_lineno_pos, start)
+            last_lineno_pos = start
+            if "@@Import@@" not in dict:
+                dict["@@Import@@"] = Imports(module, file)
+            for name in names:
+                dict["@@Import@@"].addImport(name, [], lineno)
+        
+        elif m.start("ImportFrom") >= 0:
+            # from module import stuff
+            mod = m.group("ImportFromPath")
+            namesLines = (m.group("ImportFromList")
+                          .replace("(", "").replace(")", "")
+                          .replace("\\", "")
+                          .strip().splitlines())
+            namesLines = [line.split("#")[0].strip()
+                          for line in namesLines]
+            names = [n.strip() for n in
+                     "".join(namesLines)
+                     .split(',')]
+            lineno = lineno + src.count('\n', last_lineno_pos, start)
+            last_lineno_pos = start
+            if "@@Import@@" not in dict:
+                dict["@@Import@@"] = Imports(module, file)
+            dict["@@Import@@"].addImport(mod, names, lineno)
+        
         elif m.start("ConditionalDefine") >= 0:
             # a conditional function/method definition
             thisindent = _indent(m.group("ConditionalDefineIndent"))

eric ide

mercurial