def resolve_name(self, what, name): """ Determine what module to import and what attribute to document. Returns a tuple of: the full name, the module name, a path of names to get via getattr, the signature and return annotation. """ # first, parse the definition -- auto directives for classes and functions # can contain a signature which is then used instead of an autogenerated one try: path, base, args, retann = py_sig_re.match(name).groups() except: self.warn('invalid signature for auto%s (%r)' % (what, name)) return # fullname is the fully qualified name, base the name after the last dot fullname = (path or '') + base if what == 'module': if args or retann: self.warn('ignoring signature arguments and return annotation ' 'for automodule %s' % fullname) return fullname, fullname, [], None, None elif what in ('class', 'exception', 'function'): if path: mod = path.rstrip('.') else: mod = None # if documenting a toplevel object without explicit module, it can # be contained in another auto directive ... if hasattr(self.env, 'autodoc_current_module'): mod = self.env.autodoc_current_module # ... or in the scope of a module directive if not mod: mod = self.env.currmodule return fullname, mod, [base], args, retann else: if path: mod_cls = path.rstrip('.') else: mod_cls = None # if documenting a class-level object without path, there must be a # current class, either from a parent auto directive ... if hasattr(self.env, 'autodoc_current_class'): mod_cls = self.env.autodoc_current_class # ... or from a class directive if mod_cls is None: mod_cls = self.env.currclass # ... if still None, there's no way to know if mod_cls is None: return fullname, None, [], args, retann mod, cls = rpartition(mod_cls, '.') # if the module name is still missing, get it like above if not mod and hasattr(self.env, 'autodoc_current_module'): mod = self.env.autodoc_current_module if not mod: mod = self.env.currmodule return fullname, mod, [cls, base], args, retann
def resolve_name(self, what, name): """ Determine what module to import and what attribute to document. Returns a tuple of: the full name, the module name, a path of names to get via getattr, the signature and return annotation. """ # first, parse the definition -- auto directives for classes and functions # can contain a signature which is then used instead of an autogenerated one try: path, base, args, retann = py_sig_re.match(name).groups() except: self.warn('invalid signature for auto%s (%r)' % (what, name)) return # fullname is the fully qualified name, base the name after the last dot fullname = (path or '') + base if what == 'module': if args or retann: self.warn('ignoring signature arguments and return annotation ' 'for automodule %s' % fullname) return fullname, fullname, [], None, None elif what in ('class', 'exception', 'function'): if path: mod = path.rstrip('.') else: mod = None # if documenting a toplevel object without explicit module, it can # be contained in another auto directive ... if hasattr(self.env, 'autodoc_current_module'): mod = self.env.autodoc_current_module # ... or in the scope of a module directive if not mod: mod = self.env.currmodule return fullname, mod, [base], args, retann else: if path: mod_cls = path.rstrip('.') else: mod_cls = None # if documenting a class-level object without path, there must be a # current class, either from a parent auto directive ... if hasattr(self.env, 'autodoc_current_class'): mod_cls = self.env.autodoc_current_class # ... or from a class directive if mod_cls is None: mod_cls = self.env.currclass mod, cls = rpartition(mod_cls, '.') # if the module name is still missing, get it like above if not mod and hasattr(self.env, 'autodoc_current_module'): mod = self.env.autodoc_current_module if not mod: mod = self.env.currmodule return fullname, mod, [cls, base], args, retann
def _import_class_or_module(self, name): """ Import a class using its fully-qualified *name*. """ try: path, base, signature = py_sig_re.match(name).groups() except: raise ValueError( "Invalid class or module '%s' specified for inheritance diagram" % name) fullname = (path or '') + base path = path and path.rstrip('.') if not path: raise ValueError( "Invalid class or module '%s' specified for inheritance diagram" % name) try: module = __import__(path, None, None, []) except ImportError: raise ValueError( "Could not import class or module '%s' specified for inheritance diagram" % name) try: todoc = module for comp in fullname.split('.')[1:]: todoc = getattr(todoc, comp) except AttributeError: raise ValueError( "Could not find class or module '%s' specified for inheritance diagram" % name) # If a class, just return it if inspect.isclass(todoc): return [todoc] elif inspect.ismodule(todoc): classes = [] for cls in todoc.__dict__.values(): if inspect.isclass(cls) and cls.__module__ == todoc.__name__: classes.append(cls) return classes raise ValueError("'%s' does not resolve to a class or module" % name)
def _import_class_or_module(self, name): """ Import a class using its fully-qualified *name*. """ try: path, base, signature = py_sig_re.match(name).groups() except: raise ValueError( "Invalid class or module '%s' specified for inheritance diagram" % name) fullname = (path or '') + base path = path and path.rstrip('.') if not path: raise ValueError( "Invalid class or module '%s' specified for inheritance diagram" % name) try: module = __import__(path, None, None, []) except ImportError: raise ValueError( "Could not import class or module '%s' specified for inheritance diagram" % name) try: todoc = module for comp in fullname.split('.')[1:]: todoc = getattr(todoc, comp) except AttributeError: raise ValueError( "Could not find class or module '%s' specified for inheritance diagram" % name) # If a class, just return it if inspect.isclass(todoc): return [todoc] elif inspect.ismodule(todoc): classes = [] for cls in todoc.__dict__.values(): if inspect.isclass(cls) and cls.__module__ == todoc.__name__: classes.append(cls) return classes raise ValueError( "'%s' does not resolve to a class or module" % name)
def generate_rst(what, name, members, options, add_content, document, lineno, indent=u'', filename_set=None, check_module=False): env = document.settings.env result = None # first, parse the definition -- auto directives for classes and functions # can contain a signature which is then used instead of an autogenerated one try: path, base, signature, retann = py_sig_re.match(name).groups() except: warning = document.reporter.warning( 'invalid signature for auto%s (%r)' % (what, name), line=lineno) return [warning], result # fullname is the fully qualified name, base the name after the last dot fullname = (path or '') + base # path is the name up to the last dot path = path and path.rstrip('.') warnings = [] # determine what module to import -- mod is the module name, objpath the # path of names to get via getattr mod = None if what == 'module': mod = fullname if signature: warnings.append( document.reporter.warning( 'ignoring arguments for automodule %s' % mod, line=lineno)) objpath = [] elif what in ('class', 'exception', 'function'): if path: mod = path else: # if documenting a toplevel object without explicit module, it can # be contained in another auto directive ... if hasattr(env, 'autodoc_current_module'): mod = env.autodoc_current_module # ... or in the scope of a module directive if not mod: mod = env.currmodule objpath = [base] else: if path: mod_cls = path else: # if documenting a class-level object without path, there must be a # current class, either from a parent auto directive ... if hasattr(env, 'autodoc_current_class'): mod_cls = env.autodoc_current_class # ... or from a class directive if not mod_cls: mod_cls = env.currclass mod, cls = rpartition(mod_cls, '.') # if the module name is still missing, get it like above if not mod and hasattr(env, 'autodoc_current_module'): mod = env.autodoc_current_module if not mod: mod = env.currmodule objpath = [cls, base] # by this time, a module *must* be determined if mod is None: warnings.append( document.reporter.warning( 'don\'t know which module to import for autodocumenting %r ' '(try placing a "module" or "currentmodule" directive in the document, ' 'or giving an explicit module name)' % fullname, line=lineno)) return warnings, result # the name to put into the generated directive -- doesn't contain the module name_in_directive = '.'.join(objpath) or mod # now, import the module and get docstring(s) of object to document try: todoc = module = __import__(mod, None, None, ['foo']) if hasattr(module, '__file__') and module.__file__: modfile = module.__file__ if modfile[-4:].lower() in ('.pyc', '.pyo'): modfile = modfile[:-1] if filename_set is not None: filename_set.add(modfile) else: modfile = None # e.g. for builtin and C modules for part in objpath: todoc = getattr(todoc, part) except (ImportError, AttributeError): warnings.append( document.reporter.warning( 'autodoc can\'t import/find %s %r, check your spelling ' 'and sys.path' % (what, str(fullname)), line=lineno)) return warnings, result # check __module__ of object if wanted (for members not given explicitly) if check_module: if hasattr(todoc, '__module__'): if todoc.__module__ != mod: return warnings, result # format the object's signature, if any if signature is not None: # signature given explicitly -- the parentheses were stripped by the regex args = '(%s)' % signature if retann: args += retann else: try: args = format_signature(what, todoc) except Exception, err: warnings.append( document.reporter.warning( 'error while formatting signature for %s: %s' % (fullname, err), line=lineno)) args = ''
def generate_rst(what, name, members, options, add_content, document, lineno, indent=u'', filename_set=None, check_module=False): env = document.settings.env result = None # first, parse the definition -- auto directives for classes and functions # can contain a signature which is then used instead of an autogenerated one try: path, base, signature, retann = py_sig_re.match(name).groups() except: warning = document.reporter.warning( 'invalid signature for auto%s (%r)' % (what, name), line=lineno) return [warning], result # fullname is the fully qualified name, base the name after the last dot fullname = (path or '') + base # path is the name up to the last dot path = path and path.rstrip('.') warnings = [] # determine what module to import -- mod is the module name, objpath the # path of names to get via getattr mod = None if what == 'module': mod = fullname if signature: warnings.append(document.reporter.warning( 'ignoring arguments for automodule %s' % mod, line=lineno)) objpath = [] elif what in ('class', 'exception', 'function'): if path: mod = path else: # if documenting a toplevel object without explicit module, it can # be contained in another auto directive ... if hasattr(env, 'autodoc_current_module'): mod = env.autodoc_current_module # ... or in the scope of a module directive if not mod: mod = env.currmodule objpath = [base] else: if path: mod_cls = path else: # if documenting a class-level object without path, there must be a # current class, either from a parent auto directive ... if hasattr(env, 'autodoc_current_class'): mod_cls = env.autodoc_current_class # ... or from a class directive if not mod_cls: mod_cls = env.currclass mod, cls = rpartition(mod_cls, '.') # if the module name is still missing, get it like above if not mod and hasattr(env, 'autodoc_current_module'): mod = env.autodoc_current_module if not mod: mod = env.currmodule objpath = [cls, base] # by this time, a module *must* be determined if mod is None: warnings.append(document.reporter.warning( 'don\'t know which module to import for autodocumenting %r ' '(try placing a "module" or "currentmodule" directive in the document, ' 'or giving an explicit module name)' % fullname, line=lineno)) return warnings, result # the name to put into the generated directive -- doesn't contain the module name_in_directive = '.'.join(objpath) or mod # now, import the module and get docstring(s) of object to document try: todoc = module = __import__(mod, None, None, ['foo']) if hasattr(module, '__file__') and module.__file__: modfile = module.__file__ if modfile[-4:].lower() in ('.pyc', '.pyo'): modfile = modfile[:-1] if filename_set is not None: filename_set.add(modfile) else: modfile = None # e.g. for builtin and C modules for part in objpath: todoc = getattr(todoc, part) except (ImportError, AttributeError): warnings.append(document.reporter.warning( 'autodoc can\'t import/find %s %r, check your spelling ' 'and sys.path' % (what, str(fullname)), line=lineno)) return warnings, result # check __module__ of object if wanted (for members not given explicitly) if check_module: if hasattr(todoc, '__module__'): if todoc.__module__ != mod: return warnings, result # format the object's signature, if any if signature is not None: # signature given explicitly -- the parentheses were stripped by the regex args = '(%s)' % signature if retann: args += retann else: try: args = format_signature(what, todoc) except Exception, err: warnings.append(document.reporter.warning( 'error while formatting signature for %s: %s' % (fullname, err), line=lineno)) args = ''