diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-03-01 16:51:57 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-03-02 12:34:17 +0000 |
commit | e9e157032ab383c894c38517a047860232e45482 (patch) | |
tree | 4f3c7901371f31f5f4baadcaa5ba5486c06499fb /sources/pyside2/doc | |
parent | 44cb6c51e6c3b43376f284941454dc8c13b81c3f (diff) |
Documentation/inheritance_diagram.py: Fix import logic
The script tried to import a class or a module to obtain
an introspectable object, which failed for nested classes
like PySide2.QtCore.QStateMachine.SignalEvent, resulting in
numerous warnings like:
WARNING: Could not import class or module 'QStateMachine.SignalEvent' specified for inheritance diagram
Rewrite the import to strip off the path components in a loop until
the import succeeds and then walk up the attributes again to obtain
the object.
Task-number: PYSIDE-363
Change-Id: I33c6b4c6145b501a2f8f9ef3325610fefad9580d
Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/pyside2/doc')
-rw-r--r-- | sources/pyside2/doc/inheritance_diagram.py | 74 |
1 files changed, 36 insertions, 38 deletions
diff --git a/sources/pyside2/doc/inheritance_diagram.py b/sources/pyside2/doc/inheritance_diagram.py index cd49906a5..038c22f29 100644 --- a/sources/pyside2/doc/inheritance_diagram.py +++ b/sources/pyside2/doc/inheritance_diagram.py @@ -52,15 +52,38 @@ from docutils.parsers.rst import directives from sphinx.ext.graphviz import render_dot_html, render_dot_latex from sphinx.util.compat import Directive - -class_sig_re = re.compile(r'''^([\w.]*\.)? # module names - (\w+) \s* $ # class/final module name - ''', re.VERBOSE) - - class InheritanceException(Exception): pass +# When passed something like: +# PySide2.QtCore.QStateMachine.SignalEvent +# try to import the underlying module and return a +# handle to the object. In a loop, import +# PySide2.QtCore.QStateMachine.SignalEvent +# PySide2.QtCore.QStateMachine +# PySide2.QtCore +# until the import succeeds and walk up the attributes +# to obtain the object + +def importClassOrModule(name): + components = name.split('.') + for i in range(len(components), 0, -1): + importPath = '.'.join(components[: i]) + try: + __import__(importPath) + except ImportError: + continue + if i == len(components): + return sys.modules[importPath] + remaining = components[i :] + cls = sys.modules[importPath] + for component in remaining: + try: + cls = getattr(cls, component) + except Exception: # No such attribute + return None + return cls + return None class InheritanceGraph(object): """ @@ -86,38 +109,13 @@ class InheritanceGraph(object): """ Import a class using its fully-qualified *name*. """ - try: - path, base = class_sig_re.match(name).groups() - except (AttributeError, ValueError): - raise InheritanceException('Invalid class or module %r specified ' - 'for inheritance diagram' % name) - - fullname = (path or '') + base - path = (path and path.rstrip('.') or '') - - # two possibilities: either it is a module, then import it - try: - __import__(fullname) - todoc = sys.modules[fullname] - except ImportError: - # else it is a class, then import the module - if not path: - if currmodule: - # try the current module - path = currmodule - else: - raise InheritanceException( - 'Could not import class %r specified for ' - 'inheritance diagram' % base) - try: - __import__(path) - todoc = getattr(sys.modules[path], base) - except (ImportError, AttributeError): - raise InheritanceException( - 'Could not import class or module %r specified for ' - 'inheritance diagram' % (path + '.' + base)) - - # If a class, just return it + todoc = importClassOrModule(name) + if not todoc and currmodule is not None: + todoc = importClassOrModule(currmodule + '.' + name) + if not todoc: + moduleStr = '(module {})'.format(currmodule) if currmodule else '' + raise InheritanceException('Could not import class {} specified for ' + 'inheritance diagram {}.'.format(name, moduleStr)) if inspect.isclass(todoc): return [todoc] elif inspect.ismodule(todoc): |