Movatterモバイル変換


[0]ホーム

URL:


Packagepdoc

Python packagepdoc provides types, functions, and a command-lineinterface for accessing public documentation of Python modules, andfor presenting it in a user-friendly, industry-standard open format.It is best suited for small- to medium-sized projects with tidy,hierarchical APIs.

pdoc extracts documentation of:

Documentation is extracted from live objects'docstringsusing Python's__doc__ attribute1. Documentation forvariables is found by examining objects' abstract syntax trees.

What objects are documented?

pdoc only extractspublic API documentation.2Code objects (modules, variables, functions, classes, methods) are consideredpublic in the modules where they are defined (vs. imported from somewhere else)as long as theiridentifiers don't begin with an underscore ( _ ).3If a module defines__all__, then only the identifiers containedin this list are considered public, regardless of where they were defined.

This can be fine-tuned through__pdoc__ dict.

Where doespdoc get documentation from?

In Python, objects like modules, functions, classes, and methodshave a special attribute__doc__ which contains that object'sdocumentation string (docstring).For example, the following code defines a function with a docstringand shows how to access its contents:

>>> def test():...     """This is a docstring."""...     pass...>>> test.__doc__'This is a docstring.'

It's pretty much the same with classes and modules.SeePEP-257 for Python docstring conventions.

These docstrings are set as descriptions for each module, class,function, and method listed in the documentation produced bypdoc.

pdoc extends the standard use of docstrings in Python in twoimportant ways: by allowing methods to inherit docstrings, andby introducing syntax for docstrings for variables.

Docstrings inheritance

pdoc considers methods' docstrings inherited from superclass methods',following the normal class inheritance patterns.Consider the following code example:

>>> class A:...     def test(self):...         """Docstring for A."""...         pass...>>> class B(A):...     def test(self):...         pass...>>> A.test.__doc__'Docstring for A.'>>> B.test.__doc__None

In Python, the docstring forB.test doesn't exist, even though adocstring was defined forA.test.Contrary, whenpdoc generates documentation for code such as above,it will automatically attach the docstring forA.test toB.test if the latter doesn't define its own.In the default HTML template, such inherited docstrings are greyed out.

Docstrings for variables

Python by itselfdoesn't allow docstrings attached to variables.However,pdoc supports documenting module (or global)variables, class variables, and object instance variables viatwo different mechanisms:PEP-224 and#: doc-comments.

For example:

module_variable = 1"""PEP 224 docstring for module_variable."""class C:    #: Documentation comment for class_variable    #: spanning over three lines.    class_variable = 2  #: Assignment line is included.    def __init__(self):        #: Instance variable's doc-comment        self.variable = 3        """But note, PEP 224 docstrings take precedence."""

While the resulting variables have no__doc__ attribute,pdoc compensates by reading the source code (when available)and parsing the syntax tree.

By convention, variables defined in a class'__init__ methodand attached toself are considered and documented asinstance variables.

Class and instance variables can alsoinherit docstrings.

Overriding docstrings with__pdoc__

Docstrings for objects can be disabled, overridden, or whitelisted with a specialmodule-level dictionary__pdoc__. Thekeysshould be string identifiers within the scope of the module or,alternatively, fully-qualified reference names. E.g. for instancevariableself.variable of classC, its module-level identifier is'C.variable', andsome_package.module.C.variable its refname.

If__pdoc__[key] = False, thenkey (and its members) will beexcluded from the documentation of the module.

Conversely, if__pdoc__[key] = True, thenkey (and its public members) will beincluded in the documentation of the module. This can be used toinclude documentation ofprivate objects,including special functions such as__call__, which are ignored by default.

Alternatively, thevalues of__pdoc__ can be theoverriding docstrings.This feature is useful when there's no feasible way ofattaching a docstring to something. A good example is anamedtuple:

__pdoc__ = {}Table = namedtuple('Table', ['types', 'names', 'rows'])__pdoc__['Table.types'] = 'Types for each column in the table.'__pdoc__['Table.names'] = 'The names of each column in the table.'__pdoc__['Table.rows'] = 'Lists corresponding to each row in the table.'

pdoc will then showTable as a class with documentation for thetypes,names androws members.

Note

The assignments to__pdoc__ need to be placed where they'll beexecuted when the module is imported. For example, at the top levelof a module or in the definition of a class.

Supported Docstring Formats

Currently, pure Markdown (withextensions),numpydoc,andGoogle-style docstrings formats are supported,along with somereST directives.

Additionally, iflatex_mathtemplate config option is enabled,LaTeX math syntax is supported when placed betweenrecognized delimiters:\(...\) for inline equations and\[...\] or$$...$$ for block equations. Note, you need to escapeyour backslashes in Python docstrings (\\(,\\frac{}{}, …)or, alternatively, useraw string literals.

SupportedreST directives

The followingreST directives should work:

Linking To Other Identifiers

In your documentation, you may refer to other identifiers inyour modules. When exporting to HTML, linking is automaticallydone whenever you surround an identifier withbackticks ( ` ).Unless within the current module,the identifier name must be fully qualified, for example`pdoc.Doc.docstring` is correct (and will link toDoc.docstring) while`Doc.docstring`only works withinpdoc module.

Command-line interface

pdoc includes a feature-rich "binary" program for producingHTML and plain text documentation of your modules.For example, to produce HTML documentation of your whole packagein subdirectory 'build' of the current directory, using the defaultHTML template, run:

$ pdoc --html --output-dir build my_package

If you want to omit the source code preview, run:

$ pdoc --html --config show_source_code=False my_package

Find additional template configuration tunables incustom templatessection below.

To run a local HTTP server while developing your package or writingdocstrings for it, run:

$ pdoc --http : my_package

To re-build documentation as part of your continuous integration (CI)best practice, i.e. ensuring all reference links are correct andup-to-date, make warnings error loudly by settings the environmentvariablePYTHONWARNINGS before running pdoc:

$ export PYTHONWARNINGS='error::UserWarning'

For brief usage instructions, type:

$ pdoc --help

Even more usage examples can be found in theFAQ.

Programmatic Usage

The main entry point isModule which wraps a module objectand recursively imports and wraps any submodules and their members.

After all related modules are wrapped (related modules are those thatshare the sameContext), you need to calllink_inheritance() with the usedContext instance toestablish class inheritance links.

Afterwards, you can useModule.html() andModule.text()methods to output documentation in the desired format.For example:

import pdocmodules = ['a', 'b']  # Public submodules are auto-importedcontext = pdoc.Context()modules = [pdoc.Module(mod, context=context)           for mod in modules]pdoc.link_inheritance(context)def recursive_htmls(mod):    yield mod.name, mod.html()    for submod in mod.submodules():        yield from recursive_htmls(submod)for mod in modules:    for module_name, html in recursive_htmls(mod):        ...  # Process

When documenting a single module, you might findfunctionshtml() andtext() handy.For importing arbitrary modules/files, useimport_module().

Alternatively, use therunnable script included with this package.

Custom Templates

To override the built-in HTML/CSS and plain text templates, copythe relevant templates frompdoc/templates directory into a directoryof your choosing and edit them. When you runpdoc commandafterwards, pass the directory path as a parameter to the--template-dir switch.

Tip

If you find you only need to apply minor alterations to the HTML template,see if you can do so by overriding just some of the following, placeholdersub-templates:

  • config.mako: Basic template configuration, affects the way templatesare rendered.
  • head.mako: Included just before</head>. Best for adding resources and styles.
  • logo.mako: Included at the very top of the navigation sidebar. Empty by default.
  • credits.mako: Included in the footer, right before pdoc version string.

Seedefault template files for reference.

Tip

You can also alter individualconfig.mako preferences using the--config command-line switch.

If working withpdoc programmatically,prepend the directory withmodified templates into thedirectories list of thetpl_lookup object.

Compatibility

pdoc requires Python 3.7+.The last version to support Python 2.x ispdoc3 0.3.x.

Contributing

pdoc ison GitHub. Bug reports and pull requests are welcome.

License

pdoc is licensed under the terms of GNUAGPL-3.0 or later,meaning you can use it for any reasonable purpose and remain incomplete ownership of all the documentation you produce,but you are also encouraged to make sure any upgrades topdocitself find their way back to the community.


  1. Documented modules areexecuted in order to provide__doc__attributes. Anynon-fenced global code in imported modules willaffect the current runtime environment

  2. Here, public API refers to the API that is made availableto your project end-users, not the public API e.g. of aprivate class that can be reasonably extended elsewhereby your project developers. 

  3. Prefixing private, implementation-specific objects withan underscore isa common convention

Sub-modules

pdoc.cli

pdoc's CLI interface and helper functions.

pdoc.html_helpers

Helper functions for HTML output.

pdoc.test

Unit tests for pdoc package.

Global variables

vartpl_lookup

Amako.lookup.TemplateLookup object that knows how to load templatesfrom the file system. You may add additional paths by modifying theobject'sdirectories attribute.

Functions

defhtml(module_name, docfilter=None, reload=False, skip_errors=False, **kwargs) ‑> str
Expand source codeBrowse git
def html(module_name, docfilter=None, reload=False, skip_errors=False, **kwargs) -> str:    """    Returns the documentation for the module `module_name` in HTML    format. The module must be a module or an importable string.    `docfilter` is an optional predicate that controls which    documentation objects are shown in the output. It is a function    that takes a single argument (a documentation object) and returns    `True` or `False`. If `False`, that object will not be documented.    """    mod = Module(import_module(module_name, reload=reload, skip_errors=False),                 docfilter=docfilter, skip_errors=skip_errors)    link_inheritance()    return mod.html(**kwargs)

Returns the documentation for the modulemodule_name in HTMLformat. The module must be a module or an importable string.

docfilter is an optional predicate that controls whichdocumentation objects are shown in the output. It is a functionthat takes a single argument (a documentation object) and returnsTrue orFalse. IfFalse, that object will not be documented.

defimport_module(module: str | module, *, reload: bool = False, skip_errors: bool = False) ‑> module
Expand source codeBrowse git
def import_module(        module: Union[str, ModuleType],        *,        reload: bool = False,        skip_errors: bool = False,) -> ModuleType:    """    Return module object matching `module` specification (either a python    module path or a filesystem path to file/directory).    """    @contextmanager    def _module_path(module):        from os.path import abspath, dirname, isfile, isdir, split        path = '_pdoc_dummy_nonexistent'        module_name = inspect.getmodulename(module)        if isdir(module):            path, module = split(abspath(module))        elif isfile(module) and module_name:            path, module = dirname(abspath(module)), module_name        try:            sys.path.insert(0, path)            yield module        finally:            sys.path.remove(path)    if isinstance(module, Module):        module = module.obj    if isinstance(module, str):        with _module_path(module) as module_path:            try:                module = importlib.import_module(module_path)            except Exception as e:                msg = f'Error importing {module!r}: {e.__class__.__name__}: {e}'                if not skip_errors:                    raise ImportError(msg)                warn(msg, category=Module.ImportWarning, stacklevel=2)                module = ModuleType(module_path)    assert inspect.ismodule(module)    # If this is pdoc itself, return without reloading. Otherwise later    # `isinstance(..., pdoc.Doc)` calls won't work correctly.    if reload and not module.__name__.startswith(__name__):        module = importlib.reload(module)        # We recursively reload all submodules, in case __all_ is used - cf. issue #264        for mod_key, mod in list(sys.modules.items()):            if mod_key.startswith(module.__name__):                importlib.reload(mod)    return module

Return module object matchingmodule specification (either a pythonmodule path or a filesystem path to file/directory).

deflink_inheritance(context: Context | None = None)
Expand source codeBrowse git
def link_inheritance(context: Optional[Context] = None):    """    Link inheritance relationsships between `pdoc.Class` objects    (and between their members) of all `pdoc.Module` objects that    share the provided `context` (`pdoc.Context`).    You need to call this if you expect `pdoc.Doc.inherits` and    inherited `pdoc.Doc.docstring` to be set correctly.    """    if context is None:        context = _global_context    graph = {cls: set(cls.mro(only_documented=True))             for cls in _filter_type(Class, context)}    for cls in _toposort(graph):        cls._fill_inheritance()    for module in _filter_type(Module, context):        module._link_inheritance()

Link inheritance relationsships betweenClass objects(and between their members) of allModule objects thatshare the providedcontext (Context).

You need to call this if you expectDoc.inherits andinheritedDoc.docstring to be set correctly.

defmaybe_lru_cache(func)
Expand source codeBrowse git
def maybe_lru_cache(func):    cached_func = lru_cache()(func)    @wraps(func)    def wrapper(*args):        try:            return cached_func(*args)        except TypeError:            return func(*args)    return wrapper
defreset()
Expand source codeBrowse git
def reset():    """Resets the global `pdoc.Context` to the initial (empty) state."""    global _global_context    _global_context.clear()    # Clear LRU caches    for func in (_get_type_hints,                 _is_blacklisted,                 _is_whitelisted):        func.cache_clear()    for cls in (Doc, Module, Class, Function, Variable, External):        for _, method in inspect.getmembers(cls):            if isinstance(method, property):                method = method.fget            if hasattr(method, 'cache_clear'):                method.cache_clear()

Resets the globalContext to the initial (empty) state.

deftext(module_name, docfilter=None, reload=False, skip_errors=False, **kwargs) ‑> str
Expand source codeBrowse git
def text(module_name, docfilter=None, reload=False, skip_errors=False, **kwargs) -> str:    """    Returns the documentation for the module `module_name` in plain    text format suitable for viewing on a terminal.    The module must be a module or an importable string.    `docfilter` is an optional predicate that controls which    documentation objects are shown in the output. It is a function    that takes a single argument (a documentation object) and returns    `True` or `False`. If `False`, that object will not be documented.    """    mod = Module(import_module(module_name, reload=reload, skip_errors=False),                 docfilter=docfilter, skip_errors=skip_errors)    link_inheritance()    return mod.text(**kwargs)

Returns the documentation for the modulemodule_name in plaintext format suitable for viewing on a terminal.The module must be a module or an importable string.

docfilter is an optional predicate that controls whichdocumentation objects are shown in the output. It is a functionthat takes a single argument (a documentation object) and returnsTrue orFalse. IfFalse, that object will not be documented.

Classes

classClass(name: str,
module: Module,
obj,
*,
docstring: str | None = None)
Expand source codeBrowse git
class Class(Doc):    """    Representation of a class' documentation.    """    def __init__(self, name: str, module: Module, obj, *, docstring: Optional[str] = None):        assert inspect.isclass(obj)        if docstring is None:            init_doc = inspect.getdoc(obj.__init__) or ''            if init_doc == object.__init__.__doc__:                init_doc = ''            docstring = f'{inspect.getdoc(obj) or ""}\n\n{init_doc}'.strip()        super().__init__(name, module, obj, docstring=docstring)        self.doc: Dict[str, Union[Function, Variable]] = {}        """A mapping from identifier name to a `pdoc.Doc` objects."""        # Annotations for filtering.        # Use only own, non-inherited annotations (the rest will be inherited)        annotations = getattr(self.obj, '__annotations__', {})        public_objs = []        for _name, obj in _getmembers_all(self.obj):            # Filter only *own* members. The rest are inherited            # in Class._fill_inheritance()            if ((_name in self.obj.__dict__ or                 _name in annotations) and                    (_is_public(_name) or                     _is_whitelisted(_name, self))):                if _is_blacklisted(_name, self):                    self.module._context.blacklisted.add(f'{self.refname}.{_name}')                    continue                obj = inspect.unwrap(obj)                public_objs.append((_name, obj))        def definition_order_index(                name,                _annot_index=list(annotations).index,                _dict_index=list(self.obj.__dict__).index):            try:                return _dict_index(name)            except ValueError:                pass            try:                return _annot_index(name) - len(annotations)  # sort annotated first            except ValueError:                return 9e9        public_objs.sort(key=lambda i: definition_order_index(i[0]))        var_docstrings, instance_var_docstrings = _pep224_docstrings(self)        # Convert the public Python objects to documentation objects.        for name, obj in public_objs:            if _is_function(obj):                self.doc[name] = Function(                    name, self.module, obj, cls=self)            else:                self.doc[name] = Variable(                    name, self.module,                    docstring=(                        var_docstrings.get(name) or                        (inspect.isclass(obj) or _is_descriptor(obj)) and inspect.getdoc(obj)),                    cls=self,                    kind="prop" if isinstance(obj, property) else "var",                    obj=_is_descriptor(obj) and obj or None,                    instance_var=(_is_descriptor(obj) or                                  name in getattr(self.obj, '__slots__', ()) or                                  (is_dataclass(self.obj) and name in annotations)))        for name, docstring in instance_var_docstrings.items():            self.doc[name] = Variable(                name, self.module, docstring, cls=self,                obj=getattr(self.obj, name, None),                instance_var=True)    @staticmethod    def _method_type(cls: type, name: str):        """        Returns `None` if the method `name` of class `cls`        is a regular method. Otherwise, it returns        `classmethod` or `staticmethod`, as appropriate.        """        func = getattr(cls, name, None)        if inspect.ismethod(func):            # If the function is already bound, it's a classmethod.            # Regular methods are not bound before initialization.            return classmethod        for c in inspect.getmro(cls):            if name in c.__dict__:                if isinstance(c.__dict__[name], staticmethod):                    return staticmethod                return None        raise RuntimeError(f"{cls}.{name} not found")    @property    def refname(self) -> str:        return f'{self.module.name}.{self.qualname}'    def mro(self, only_documented=False) -> List['Class']:        """        Returns a list of ancestor (superclass) documentation objects        in method resolution order.        The list will contain objects of type `pdoc.Class`        if the types are documented, and `pdoc.External` otherwise.        """        classes = [cast(Class, self.module.find_class(c))                   for c in inspect.getmro(self.obj)                   if c not in (self.obj, object)]        if self in classes:            # This can contain self in case of a class inheriting from            # a class with (previously) the same name. E.g.            #            #     class Loc(namedtuple('Loc', 'lat lon')): ...            #            # We remove it from ancestors so that toposort doesn't break.            classes.remove(self)        if only_documented:            classes = _filter_type(Class, classes)        return classes    def subclasses(self) -> List['Class']:        """        Returns a list of subclasses of this class that are visible to the        Python interpreter (obtained from `type.__subclasses__()`).        The objects in the list are of type `pdoc.Class` if available,        and `pdoc.External` otherwise.        """        return sorted(cast(Class, self.module.find_class(c))                      for c in type.__subclasses__(self.obj))    def params(self, *, annotate=False, link=None) -> List[str]:        """        Return a list of formatted parameters accepted by the        class constructor (method `__init__`). See `pdoc.Function.params`.        """        name = self.name + '.__init__'        qualname = self.qualname + '.__init__'        refname = self.refname + '.__init__'        exclusions = self.module.__pdoc__        if name in exclusions or qualname in exclusions or refname in exclusions:            return []        return Function._params(self, annotate=annotate, link=link, module=self.module)    def _filter_doc_objs(self, type: Type[T], include_inherited=True,                         filter_func: Callable[[T], bool] = lambda x: True,                         sort=True) -> List[T]:        result = [obj for obj in _filter_type(type, self.doc)                  if (include_inherited or not obj.inherits) and filter_func(obj)]        return sorted(result) if sort else result    def class_variables(self, include_inherited=True, sort=True) -> List['Variable']:        """        Returns an optionally-sorted list of `pdoc.Variable` objects that        represent this class' class variables.        """        return self._filter_doc_objs(            Variable, include_inherited, lambda dobj: not dobj.instance_var,            sort)    def instance_variables(self, include_inherited=True, sort=True) -> List['Variable']:        """        Returns an optionally-sorted list of `pdoc.Variable` objects that        represent this class' instance variables. Instance variables        are those defined in a class's `__init__` as `self.variable = ...`.        """        return self._filter_doc_objs(            Variable, include_inherited, lambda dobj: dobj.instance_var,            sort)    def methods(self, include_inherited=True, sort=True) -> List['Function']:        """        Returns an optionally-sorted list of `pdoc.Function` objects that        represent this class' methods.        """        return self._filter_doc_objs(            Function, include_inherited, lambda dobj: dobj.is_method,            sort)    def functions(self, include_inherited=True, sort=True) -> List['Function']:        """        Returns an optionally-sorted list of `pdoc.Function` objects that        represent this class' static functions.        """        return self._filter_doc_objs(            Function, include_inherited, lambda dobj: not dobj.is_method,            sort)    def inherited_members(self) -> List[Tuple['Class', List[Doc]]]:        """        Returns all inherited members as a list of tuples        (ancestor class, list of ancestor class' members sorted by name),        sorted by MRO.        """        return sorted(((cast(Class, k), sorted(g))                       for k, g in groupby((i.inherits                                            for i in self.doc.values() if i.inherits),                                           key=lambda i: i.cls)),                   # type: ignore                      key=lambda x, _mro_index=self.mro().index: _mro_index(x[0]))  # type: ignore    def _fill_inheritance(self):        """        Traverses this class's ancestor list and attempts to fill in        missing documentation objects from its ancestors.        Afterwards, call to `pdoc.Class._link_inheritance()` to also        set `pdoc.Doc.inherits` pointers.        """        super_members = self._super_members = {}        for cls in self.mro(only_documented=True):            for name, dobj in cls.doc.items():                if name not in super_members and dobj.docstring:                    super_members[name] = dobj                    if name not in self.doc:                        dobj = copy(dobj)                        dobj.cls = self                        self.doc[name] = dobj                        self.module._context[dobj.refname] = dobj    def _link_inheritance(self):        """        Set `pdoc.Doc.inherits` pointers to inherited ancestors' members,        as appropriate. This must be called after        `pdoc.Class._fill_inheritance()`.        The reason this is split in two parts is that in-between        the `__pdoc__` overrides are applied.        """        if not hasattr(self, '_super_members'):            return        for name, parent_dobj in self._super_members.items():            try:                dobj = self.doc[name]            except KeyError:                # There is a key in some __pdoc__ dict blocking this member                continue            if (dobj.obj is parent_dobj.obj or                    (dobj.docstring or parent_dobj.docstring) == parent_dobj.docstring):                dobj.inherits = parent_dobj                dobj.docstring = parent_dobj.docstring        del self._super_members

Representation of a class' documentation.

Initializes a documentation object, wherename is the publicidentifier name,module is aModule object where rawPython objectobj is defined, anddocstring is itsdocumentation string. Ifdocstring is left empty, it will beread withinspect.getdoc().

Ancestors

Instance variables

vardoc

A mapping from identifier name to aDoc objects.

Methods

defclass_variables(self, include_inherited=True, sort=True) ‑> List[Variable]
Expand source codeBrowse git
def class_variables(self, include_inherited=True, sort=True) -> List['Variable']:    """    Returns an optionally-sorted list of `pdoc.Variable` objects that    represent this class' class variables.    """    return self._filter_doc_objs(        Variable, include_inherited, lambda dobj: not dobj.instance_var,        sort)

Returns an optionally-sorted list ofVariable objects thatrepresent this class' class variables.

deffunctions(self, include_inherited=True, sort=True) ‑> List[Function]
Expand source codeBrowse git
def functions(self, include_inherited=True, sort=True) -> List['Function']:    """    Returns an optionally-sorted list of `pdoc.Function` objects that    represent this class' static functions.    """    return self._filter_doc_objs(        Function, include_inherited, lambda dobj: not dobj.is_method,        sort)

Returns an optionally-sorted list ofFunction objects thatrepresent this class' static functions.

definherited_members(self) ‑> List[Tuple[Class, List[Doc]]]
Expand source codeBrowse git
def inherited_members(self) -> List[Tuple['Class', List[Doc]]]:    """    Returns all inherited members as a list of tuples    (ancestor class, list of ancestor class' members sorted by name),    sorted by MRO.    """    return sorted(((cast(Class, k), sorted(g))                   for k, g in groupby((i.inherits                                        for i in self.doc.values() if i.inherits),                                       key=lambda i: i.cls)),                   # type: ignore                  key=lambda x, _mro_index=self.mro().index: _mro_index(x[0]))  # type: ignore

Returns all inherited members as a list of tuples(ancestor class, list of ancestor class' members sorted by name),sorted by MRO.

definstance_variables(self, include_inherited=True, sort=True) ‑> List[Variable]
Expand source codeBrowse git
def instance_variables(self, include_inherited=True, sort=True) -> List['Variable']:    """    Returns an optionally-sorted list of `pdoc.Variable` objects that    represent this class' instance variables. Instance variables    are those defined in a class's `__init__` as `self.variable = ...`.    """    return self._filter_doc_objs(        Variable, include_inherited, lambda dobj: dobj.instance_var,        sort)

Returns an optionally-sorted list ofVariable objects thatrepresent this class' instance variables. Instance variablesare those defined in a class's__init__ asself.variable = ....

defmethods(self, include_inherited=True, sort=True) ‑> List[Function]
Expand source codeBrowse git
def methods(self, include_inherited=True, sort=True) -> List['Function']:    """    Returns an optionally-sorted list of `pdoc.Function` objects that    represent this class' methods.    """    return self._filter_doc_objs(        Function, include_inherited, lambda dobj: dobj.is_method,        sort)

Returns an optionally-sorted list ofFunction objects thatrepresent this class' methods.

defmro(self, only_documented=False) ‑> List[Class]
Expand source codeBrowse git
def mro(self, only_documented=False) -> List['Class']:    """    Returns a list of ancestor (superclass) documentation objects    in method resolution order.    The list will contain objects of type `pdoc.Class`    if the types are documented, and `pdoc.External` otherwise.    """    classes = [cast(Class, self.module.find_class(c))               for c in inspect.getmro(self.obj)               if c not in (self.obj, object)]    if self in classes:        # This can contain self in case of a class inheriting from        # a class with (previously) the same name. E.g.        #        #     class Loc(namedtuple('Loc', 'lat lon')): ...        #        # We remove it from ancestors so that toposort doesn't break.        classes.remove(self)    if only_documented:        classes = _filter_type(Class, classes)    return classes

Returns a list of ancestor (superclass) documentation objectsin method resolution order.

The list will contain objects of typeClassif the types are documented, andExternal otherwise.

defparams(self, *, annotate=False, link=None) ‑> List[str]
Expand source codeBrowse git
def params(self, *, annotate=False, link=None) -> List[str]:    """    Return a list of formatted parameters accepted by the    class constructor (method `__init__`). See `pdoc.Function.params`.    """    name = self.name + '.__init__'    qualname = self.qualname + '.__init__'    refname = self.refname + '.__init__'    exclusions = self.module.__pdoc__    if name in exclusions or qualname in exclusions or refname in exclusions:        return []    return Function._params(self, annotate=annotate, link=link, module=self.module)

Return a list of formatted parameters accepted by theclass constructor (method__init__). SeeFunction.params().

defsubclasses(self) ‑> List[Class]
Expand source codeBrowse git
def subclasses(self) -> List['Class']:    """    Returns a list of subclasses of this class that are visible to the    Python interpreter (obtained from `type.__subclasses__()`).    The objects in the list are of type `pdoc.Class` if available,    and `pdoc.External` otherwise.    """    return sorted(cast(Class, self.module.find_class(c))                  for c in type.__subclasses__(self.obj))

Returns a list of subclasses of this class that are visible to thePython interpreter (obtained fromtype.__subclasses__()).

The objects in the list are of typeClass if available,andExternal otherwise.

Inherited members

classContext
Expand source codeBrowse git
class Context(dict):    """    The context object that maps all documented identifiers    (`pdoc.Doc.refname`) to their respective `pdoc.Doc` objects.    You can pass an instance of `pdoc.Context` to `pdoc.Module` constructor.    All `pdoc.Module` objects that share the same `pdoc.Context` will see    (and be able to link in HTML to) each other's identifiers.    If you don't pass your own `Context` instance to `Module` constructor,    a global context object will be used.    """    __pdoc__['Context.__init__'] = False    def __init__(self, *args, **kwargs):        super().__init__(*args, **kwargs)        # A surrogate so that the check in Module._link_inheritance()        # "__pdoc__-overriden key {!r} does not exist" can see the object        # (and not warn).        self.blacklisted = getattr(args[0], 'blacklisted', set()) if args else set()

The context object that maps all documented identifiers(Doc.refname) to their respectiveDoc objects.

You can pass an instance ofContext toModule constructor.AllModule objects that share the sameContext will see(and be able to link in HTML to) each other's identifiers.

If you don't pass your ownContext instance toModule constructor,a global context object will be used.

Ancestors

  • builtins.dict
classDoc(name: str, module, obj, docstring: str = '')
Expand source codeBrowse git
class Doc:    """    A base class for all documentation objects.    A documentation object corresponds to *something* in a Python module    that has a docstring associated with it. Typically, this includes    modules, classes, functions, and methods. However, `pdoc` adds support    for extracting some docstrings from abstract syntax trees, making    (module, class or instance) variables supported too.    A special type of documentation object `pdoc.External` is used to    represent identifiers that are not part of the public interface of    a module. (The name "External" is a bit of a misnomer, since it can    also correspond to unexported members of the module, particularly in    a class's ancestor list.)    """    def __init__(self, name: str, module, obj, docstring: str = ''):        """        Initializes a documentation object, where `name` is the public        identifier name, `module` is a `pdoc.Module` object where raw        Python object `obj` is defined, and `docstring` is its        documentation string. If `docstring` is left empty, it will be        read with `inspect.getdoc()`.        """        self.module = module        """        The module documentation object that this object is defined in.        """        self.name = name        """        The identifier name for this object.        """        self.obj = obj        """        The raw python object.        """        docstring = (docstring or inspect.getdoc(obj) or '').strip()        if '.. include::' in docstring:            from pdoc.html_helpers import _ToMarkdown            docstring = _ToMarkdown.admonitions(docstring, self.module, ('include',))        self.docstring = docstring        """        The cleaned docstring for this object with any `.. include::`        directives resolved (i.e. content included).        """        self.inherits: Optional[Union[Class, Function, Variable]] = None        """        The Doc object (Class, Function, or Variable) this object inherits from,        if any.        """    def __repr__(self):        return f'<{self.__class__.__name__} {self.refname!r}>'    @property    @lru_cache()    def source(self) -> str:        """        Cleaned (dedented) source code of the Python object. If not        available, an empty string.        """        try:            lines, _ = inspect.getsourcelines(_unwrap_descriptor(self))        except (ValueError, TypeError, OSError):            return ''        return inspect.cleandoc(''.join(['\n'] + lines))    @property    def refname(self) -> str:        """        Reference name of this documentation        object, usually its fully qualified path        (e.g. <code>pdoc.Doc.refname</code>). Every        documentation object provides this property.        """        # Ok for Module and External, the rest need it overriden        return self.name    @property    def qualname(self) -> str:        """        Module-relative "qualified" name of this documentation        object, used for show (e.g. <code>Doc.qualname</code>).        """        return getattr(self.obj, '__qualname__', self.name)    @lru_cache()    def url(self, relative_to: Optional['Module'] = None, *, link_prefix: str = '',            top_ancestor: bool = False) -> str:        """        Canonical relative URL (including page fragment) for this        documentation object.        Specify `relative_to` (a `pdoc.Module` object) to obtain a        relative URL.        For usage of `link_prefix` see `pdoc.html()`.        If `top_ancestor` is `True`, the returned URL instead points to        the top ancestor in the object's `pdoc.Doc.inherits` chain.        """        if top_ancestor:            self = self._inherits_top()        if relative_to is None or link_prefix:            return link_prefix + self._url()        if self.module.name == relative_to.name:            return f'#{self.refname}'        # Otherwise, compute relative path from current module to link target        url = os.path.relpath(self._url(), relative_to.url()).replace(path.sep, '/')        # We have one set of '..' too many        if url.startswith('../'):            url = url[3:]        return url    def _url(self):        return f'{self.module._url()}#{self.refname}'    def _inherits_top(self):        """        Follow the `pdoc.Doc.inherits` chain and return the top object.        """        top = self        while top.inherits:            top = top.inherits        return top    def __lt__(self, other):        return self.refname < other.refname

A base class for all documentation objects.

A documentation object corresponds tosomething in a Python modulethat has a docstring associated with it. Typically, this includesmodules, classes, functions, and methods. However,pdoc adds supportfor extracting some docstrings from abstract syntax trees, making(module, class or instance) variables supported too.

A special type of documentation objectExternal is used torepresent identifiers that are not part of the public interface ofa module. (The name "External" is a bit of a misnomer, since it canalso correspond to unexported members of the module, particularly ina class's ancestor list.)

Initializes a documentation object, wherename is the publicidentifier name,module is aModule object where rawPython objectobj is defined, anddocstring is itsdocumentation string. Ifdocstring is left empty, it will beread withinspect.getdoc().

Subclasses

Instance variables

vardocstring

The cleaned docstring for this object with any.. include::directives resolved (i.e. content included).

varinherits

The Doc object (Class, Function, or Variable) this object inherits from,if any.

varmodule

The module documentation object that this object is defined in.

varname

The identifier name for this object.

varobj

The raw python object.

propqualname : str
Expand source codeBrowse git
@propertydef qualname(self) -> str:    """    Module-relative "qualified" name of this documentation    object, used for show (e.g. <code>Doc.qualname</code>).    """    return getattr(self.obj, '__qualname__', self.name)

Module-relative "qualified" name of this documentationobject, used for show (e.g.Doc.qualname).

proprefname : str
Expand source codeBrowse git
@propertydef refname(self) -> str:    """    Reference name of this documentation    object, usually its fully qualified path    (e.g. <code>pdoc.Doc.refname</code>). Every    documentation object provides this property.    """    # Ok for Module and External, the rest need it overriden    return self.name

Reference name of this documentationobject, usually its fully qualified path(e.g.pdoc.Doc.refname). Everydocumentation object provides this property.

propsource : str
Expand source codeBrowse git
@property@lru_cache()def source(self) -> str:    """    Cleaned (dedented) source code of the Python object. If not    available, an empty string.    """    try:        lines, _ = inspect.getsourcelines(_unwrap_descriptor(self))    except (ValueError, TypeError, OSError):        return ''    return inspect.cleandoc(''.join(['\n'] + lines))

Cleaned (dedented) source code of the Python object. If notavailable, an empty string.

Methods

defurl(self,
relative_to: ForwardRef('Module') | None = None,
*,
link_prefix: str = '',
top_ancestor: bool = False) ‑> str
Expand source codeBrowse git
@lru_cache()def url(self, relative_to: Optional['Module'] = None, *, link_prefix: str = '',        top_ancestor: bool = False) -> str:    """    Canonical relative URL (including page fragment) for this    documentation object.    Specify `relative_to` (a `pdoc.Module` object) to obtain a    relative URL.    For usage of `link_prefix` see `pdoc.html()`.    If `top_ancestor` is `True`, the returned URL instead points to    the top ancestor in the object's `pdoc.Doc.inherits` chain.    """    if top_ancestor:        self = self._inherits_top()    if relative_to is None or link_prefix:        return link_prefix + self._url()    if self.module.name == relative_to.name:        return f'#{self.refname}'    # Otherwise, compute relative path from current module to link target    url = os.path.relpath(self._url(), relative_to.url()).replace(path.sep, '/')    # We have one set of '..' too many    if url.startswith('../'):        url = url[3:]    return url

Canonical relative URL (including page fragment) for thisdocumentation object.

Specifyrelative_to (aModule object) to obtain arelative URL.

For usage oflink_prefix seehtml().

Iftop_ancestor isTrue, the returned URL instead points tothe top ancestor in the object'sDoc.inherits chain.

classExternal(name: str)
Expand source codeBrowse git
class External(Doc):    """    A representation of an external identifier. The textual    representation is the same as an internal identifier.    External identifiers are also used to represent something that is    not documented but appears somewhere in the public interface (like    the ancestor list of a class).    """    __pdoc__["External.docstring"] = """        An empty string. External identifiers do not have        docstrings.        """    __pdoc__["External.module"] = """        Always `None`. External identifiers have no associated        `pdoc.Module`.        """    __pdoc__["External.name"] = """        Always equivalent to `pdoc.External.refname` since external        identifiers are always expressed in their fully qualified        form.        """    def __init__(self, name: str):        """        Initializes an external identifier with `name`, where `name`        should be a fully qualified name.        """        super().__init__(name, None, None)    def url(self, *args, **kwargs):        """        `External` objects return absolute urls matching `/{name}.ext`.        """        return f'/{self.name}.ext'

A representation of an external identifier. The textualrepresentation is the same as an internal identifier.

External identifiers are also used to represent something that isnot documented but appears somewhere in the public interface (likethe ancestor list of a class).

Initializes an external identifier withname, wherenameshould be a fully qualified name.

Ancestors

Methods

defurl(self, *args, **kwargs)
Expand source codeBrowse git
def url(self, *args, **kwargs):    """    `External` objects return absolute urls matching `/{name}.ext`.    """    return f'/{self.name}.ext'

External objects return absolute urls matching/{name}.ext.

Inherited members

classFunction(name: str,
module: Module,
obj,
*,
cls: Class | None = None)
Expand source codeBrowse git
class Function(Doc):    """    Representation of documentation for a function or method.    """    def __init__(self, name: str, module: Module, obj, *, cls: Optional[Class] = None):        """        Same as `pdoc.Doc`, except `obj` must be a        Python function object. The docstring is gathered automatically.        `cls` should be set when this is a method or a static function        beloing to a class. `cls` should be a `pdoc.Class` object.        `method` should be `True` when the function is a method. In        all other cases, it should be `False`.        """        assert callable(obj), (name, module, obj)        super().__init__(name, module, obj)        self.cls = cls        """        The `pdoc.Class` documentation object if the function is a method.        If not, this is None.        """    @property    def is_method(self) -> bool:        """        Whether this function is a normal bound method.        In particular, static and class methods have this set to False.        """        assert self.cls        return not Class._method_type(self.cls.obj, self.name)    @property    def method(self):        warn('`Function.method` is deprecated. Use: `Function.is_method`', DeprecationWarning,             stacklevel=2)        return self.is_method    __pdoc__['Function.method'] = False    def funcdef(self) -> str:        """        Generates the string of keywords used to define the function,        for example `def` or `async def`.        """        return 'async def' if self._is_async else 'def'    @property    def _is_async(self):        """        Returns whether is function is asynchronous, either as a coroutine or an async        generator.        """        try:            # Both of these are required because coroutines aren't classified as async            # generators and vice versa.            obj = inspect.unwrap(self.obj)            return (inspect.iscoroutinefunction(obj) or                    inspect.isasyncgenfunction(obj))        except AttributeError:            return False    def return_annotation(self, *, link=None) -> str:        """Formatted function return type annotation or empty string if none."""        annot = ''        for method in (                lambda: _get_type_hints(self.obj)['return'],                # Mainly for non-property variables                lambda: _get_type_hints(cast(Class, self.cls).obj)[self.name],                # global variables                lambda: _get_type_hints(not self.cls and self.module.obj)[self.name],                # properties                lambda: inspect.signature(_unwrap_descriptor(self)).return_annotation,                # Use raw annotation strings in unmatched forward declarations                lambda: cast(Class, self.cls).obj.__annotations__[self.name],                # Extract annotation from the docstring for C builtin function                lambda: Function._signature_from_string(self).return_annotation,        ):            try:                annot = method()            except Exception:                continue            else:                break        else:            # Don't warn on variables. The annotation just isn't available.            if not isinstance(self, Variable):                warn(f"Error handling return annotation for {self!r}", stacklevel=3)        if annot is inspect.Parameter.empty or not annot:            return ''        if isinstance(annot, str):            s = annot        else:            s = _formatannotation(annot)            s = re.sub(r'\bForwardRef\((?P<quot>[\"\'])(?P<str>.*?)(?P=quot)\)',                       r'\g<str>', s)        s = s.replace(' ', '\N{NBSP}')  # Better line breaks in html signatures        if link:            from pdoc.html_helpers import _linkify            s = re.sub(r'[\w\.]+', partial(_linkify, link=link, module=self.module), s)        return s    def params(self, *, annotate: bool = False,               link: Optional[Callable[[Doc], str]] = None) -> List[str]:        """        Returns a list where each element is a nicely formatted        parameter of this function. This includes argument lists,        keyword arguments and default values, and it doesn't include any        optional arguments whose names begin with an underscore.        If `annotate` is True, the parameter strings include [PEP 484]        type hint annotations.        [PEP 484]: https://www.python.org/dev/peps/pep-0484/        """        return self._params(self, annotate=annotate, link=link, module=self.module)    @staticmethod    def _params(doc_obj, annotate=False, link=None, module=None):        try:            # We want __init__ to actually be implemented somewhere in the            # MRO to still satisfy https://github.com/pdoc3/pdoc/issues/124            if (                inspect.isclass(doc_obj.obj)                and doc_obj.obj.__init__ is not object.__init__            ):                # Remove the first argument (self) from __init__ signature                init_sig = inspect.signature(doc_obj.obj.__init__)                init_params = list(init_sig.parameters.values())                signature = init_sig.replace(parameters=init_params[1:])            else:                signature = inspect.signature(doc_obj.obj)        except ValueError:            signature = Function._signature_from_string(doc_obj)            if not signature:                return ['...']        def safe_default_value(p: inspect.Parameter):            value = p.default            if value is inspect.Parameter.empty:                return p            replacement = next((i for i in ('os.environ',                                            'sys.stdin',                                            'sys.stdout',                                            'sys.stderr',)                                if value is eval(i)), None)            if not replacement:                if isinstance(value, enum.Enum):                    replacement = str(value)                elif inspect.isclass(value):                    replacement = f'{value.__module__ or _UNKNOWN_MODULE}.{value.__qualname__}'                elif ' at 0x' in repr(value):                    replacement = re.sub(r' at 0x\w+', '', repr(value))                nonlocal link                if link and ('<' in repr(value) or '>' in repr(value)):                    import html                    replacement = html.escape(replacement or repr(value))            if replacement:                class mock:                    def __repr__(self):                        return replacement                return p.replace(default=mock())            return p        params = []        kw_only = False        pos_only = False        EMPTY = inspect.Parameter.empty        if link:            from pdoc.html_helpers import _linkify            _linkify = partial(_linkify, link=link, module=module)        for p in signature.parameters.values():  # type: inspect.Parameter            if not _is_public(p.name) and p.default is not EMPTY:                continue            if p.kind == p.POSITIONAL_ONLY:                pos_only = True            elif pos_only:                params.append("/")                pos_only = False            if p.kind == p.VAR_POSITIONAL:                kw_only = True            if p.kind == p.KEYWORD_ONLY and not kw_only:                kw_only = True                params.append('*')            p = safe_default_value(p)            if not annotate:                p = p.replace(annotation=EMPTY)            formatted = p.name            if p.annotation is not EMPTY:                annotation = _formatannotation(p.annotation).replace(' ', '\N{NBSP}')                # "Eval" forward-declarations (typing string literals)                if isinstance(p.annotation, str):                    annotation = annotation.strip("'")                if link:                    annotation = re.sub(r'[\w\.]+', _linkify, annotation)                formatted += f':\N{NBSP}{annotation}'            if p.default is not EMPTY:                if p.annotation is not EMPTY:                    formatted += f'\N{NBSP}=\N{NBSP}{repr(p.default)}'                else:                    formatted += f'={repr(p.default)}'            if p.kind == p.VAR_POSITIONAL:                formatted = f'*{formatted}'            elif p.kind == p.VAR_KEYWORD:                formatted = f'**{formatted}'            params.append(formatted)        if pos_only:            params.append("/")        return params    @staticmethod    @lru_cache()    def _signature_from_string(self):        signature = None        for expr, cleanup_docstring, filter in (                # Full proper typed signature, such as one from pybind11                (r'^{}\(.*\)(?: -> .*)?$', True, lambda s: s),                # Human-readable, usage-like signature from some Python builtins                # (e.g. `range` or `slice` or `itertools.repeat` or `numpy.arange`)                (r'^{}\(.*\)(?= -|$)', False, lambda s: s.replace('[', '').replace(']', '')),        ):            strings = sorted(re.findall(expr.format(self.name),                                        self.docstring, re.MULTILINE),                             key=len, reverse=True)            if strings:                string = filter(strings[0])                _locals, _globals = {}, {}                _globals.update({'capsule': None})  # pybind11 capsule data type                _globals.update(typing.__dict__)                _globals.update(self.module.obj.__dict__)                # Trim binding module basename from type annotations                # See: https://github.com/pdoc3/pdoc/pull/148#discussion_r407114141                module_basename = self.module.name.rsplit('.', maxsplit=1)[-1]                if module_basename in string and module_basename not in _globals:                    string = re.sub(fr'(?<!\.)\b{module_basename}\.\b', '', string)                try:                    exec(f'def {string}: pass', _globals, _locals)                except Exception:                    continue                signature = inspect.signature(_locals[self.name])                if cleanup_docstring and len(strings) == 1:                    # Remove signature from docstring variable                    self.docstring = self.docstring.replace(strings[0], '')                break        return signature    @property    def refname(self) -> str:        return f'{self.cls.refname if self.cls else self.module.refname}.{self.name}'

Representation of documentation for a function or method.

Same asDoc, exceptobj must be aPython function object. The docstring is gathered automatically.

cls should be set when this is a method or a static functionbeloing to a class.cls should be aClass object.

method should beTrue when the function is a method. Inall other cases, it should beFalse.

Ancestors

Instance variables

varcls

TheClass documentation object if the function is a method.If not, this is None.

propis_method : bool
Expand source codeBrowse git
@propertydef is_method(self) -> bool:    """    Whether this function is a normal bound method.    In particular, static and class methods have this set to False.    """    assert self.cls    return not Class._method_type(self.cls.obj, self.name)

Whether this function is a normal bound method.

In particular, static and class methods have this set to False.

Methods

deffuncdef(self) ‑> str
Expand source codeBrowse git
def funcdef(self) -> str:    """    Generates the string of keywords used to define the function,    for example `def` or `async def`.    """    return 'async def' if self._is_async else 'def'

Generates the string of keywords used to define the function,for exampledef orasync def.

defparams(self,
*,
annotate: bool = False,
link: Callable[[Doc], str] | None = None) ‑> List[str]
Expand source codeBrowse git
def params(self, *, annotate: bool = False,           link: Optional[Callable[[Doc], str]] = None) -> List[str]:    """    Returns a list where each element is a nicely formatted    parameter of this function. This includes argument lists,    keyword arguments and default values, and it doesn't include any    optional arguments whose names begin with an underscore.    If `annotate` is True, the parameter strings include [PEP 484]    type hint annotations.    [PEP 484]: https://www.python.org/dev/peps/pep-0484/    """    return self._params(self, annotate=annotate, link=link, module=self.module)

Returns a list where each element is a nicely formattedparameter of this function. This includes argument lists,keyword arguments and default values, and it doesn't include anyoptional arguments whose names begin with an underscore.

Ifannotate is True, the parameter strings includePEP 484type hint annotations.

defreturn_annotation(self, *, link=None) ‑> str
Expand source codeBrowse git
def return_annotation(self, *, link=None) -> str:    """Formatted function return type annotation or empty string if none."""    annot = ''    for method in (            lambda: _get_type_hints(self.obj)['return'],            # Mainly for non-property variables            lambda: _get_type_hints(cast(Class, self.cls).obj)[self.name],            # global variables            lambda: _get_type_hints(not self.cls and self.module.obj)[self.name],            # properties            lambda: inspect.signature(_unwrap_descriptor(self)).return_annotation,            # Use raw annotation strings in unmatched forward declarations            lambda: cast(Class, self.cls).obj.__annotations__[self.name],            # Extract annotation from the docstring for C builtin function            lambda: Function._signature_from_string(self).return_annotation,    ):        try:            annot = method()        except Exception:            continue        else:            break    else:        # Don't warn on variables. The annotation just isn't available.        if not isinstance(self, Variable):            warn(f"Error handling return annotation for {self!r}", stacklevel=3)    if annot is inspect.Parameter.empty or not annot:        return ''    if isinstance(annot, str):        s = annot    else:        s = _formatannotation(annot)        s = re.sub(r'\bForwardRef\((?P<quot>[\"\'])(?P<str>.*?)(?P=quot)\)',                   r'\g<str>', s)    s = s.replace(' ', '\N{NBSP}')  # Better line breaks in html signatures    if link:        from pdoc.html_helpers import _linkify        s = re.sub(r'[\w\.]+', partial(_linkify, link=link, module=self.module), s)    return s

Formatted function return type annotation or empty string if none.

Inherited members

classModule(module: str | module,
*,
docfilter: Callable[[Doc], bool] | None = None,
supermodule: ForwardRef('Module') | None = None,
context: Context | None = None,
skip_errors: bool = False)
Expand source codeBrowse git
class Module(Doc):    """    Representation of a module's documentation.    """    __pdoc__["Module.name"] = """        The name of this module with respect to the context/path in which        it was imported from. It is always an absolute import path.        """    def __init__(self, module: Union[ModuleType, str], *,                 docfilter: Optional[Callable[[Doc], bool]] = None,                 supermodule: Optional['Module'] = None,                 context: Optional[Context] = None,                 skip_errors: bool = False):        """        Creates a `Module` documentation object given the actual        module Python object.        `docfilter` is an optional predicate that controls which        sub-objects are documentated (see also: `pdoc.html()`).        `supermodule` is the parent `pdoc.Module` this module is        a submodule of.        `context` is an instance of `pdoc.Context`. If `None` a        global context object will be used.        If `skip_errors` is `True` and an unimportable, erroneous        submodule is encountered, a warning will be issued instead        of raising an exception.        """        if isinstance(module, str):            module = import_module(module, skip_errors=skip_errors)        super().__init__(module.__name__, self, module)        if self.name.endswith('.__init__') and not self.is_package:            self.name = self.name[:-len('.__init__')]        self._context = _global_context if context is None else context        """        A lookup table for ALL doc objects of all modules that share this context,        mainly used in `Module.find_ident()`.        """        assert isinstance(self._context, Context), \            'pdoc.Module(context=) should be a pdoc.Context instance'        self.supermodule = supermodule        """        The parent `pdoc.Module` this module is a submodule of, or `None`.        """        self.doc: Dict[str, Union[Module, Class, Function, Variable]] = {}        """A mapping from identifier name to a documentation object."""        self._is_inheritance_linked = False        """Re-entry guard for `pdoc.Module._link_inheritance()`."""        self._skipped_submodules = set()        var_docstrings, _ = _pep224_docstrings(self)        # Populate self.doc with this module's public members        public_objs = []        if hasattr(self.obj, '__all__'):            for name in self.obj.__all__:                try:                    obj = getattr(self.obj, name)                except AttributeError:                    warn(f"Module {self.module!r} doesn't contain identifier `{name}` "                         "exported in `__all__`")                else:                    if not _is_blacklisted(name, self):                        obj = inspect.unwrap(obj)                    public_objs.append((name, obj))        else:            def is_from_this_module(obj):                mod = inspect.getmodule(inspect.unwrap(obj))                return mod is None or mod.__name__ == self.obj.__name__            for name, obj in inspect.getmembers(self.obj):                if ((_is_public(name) or                     _is_whitelisted(name, self)) and                        (_is_blacklisted(name, self) or  # skips unwrapping that follows                         is_from_this_module(obj) or                         name in var_docstrings)):                    if _is_blacklisted(name, self):                        self._context.blacklisted.add(f'{self.refname}.{name}')                        continue                    obj = inspect.unwrap(obj)                    public_objs.append((name, obj))            index = list(self.obj.__dict__).index            public_objs.sort(key=lambda i: index(i[0]))        for name, obj in public_objs:            if _is_function(obj):                self.doc[name] = Function(name, self, obj)            elif inspect.isclass(obj):                self.doc[name] = Class(name, self, obj)            elif name in var_docstrings:                self.doc[name] = Variable(name, self, var_docstrings[name], obj=obj)        # If the module is a package, scan the directory for submodules        if self.is_package:            def iter_modules(paths):                """                Custom implementation of `pkgutil.iter_modules()`                because that one doesn't play well with namespace packages.                See: https://github.com/pypa/setuptools/issues/83                """                from os.path import isdir, join                for pth in paths:                    if pth.startswith("__editable__."):                        # See https://github.com/pypa/pip/issues/11380                        continue                    for file in os.listdir(pth):                        if file.startswith(('.', '__pycache__', '__init__.py')):                            continue                        module_name = inspect.getmodulename(file)                        if module_name:                            yield module_name                        if isdir(join(pth, file)) and '.' not in file:                            yield file            for root in iter_modules(self.obj.__path__):                # Ignore if this module was already doc'd.                if root in self.doc:                    continue                # Ignore if it isn't exported                if not _is_public(root) and not _is_whitelisted(root, self):                    continue                if _is_blacklisted(root, self):                    self._skipped_submodules.add(root)                    continue                assert self.refname == self.name                fullname = f"{self.name}.{root}"                m = Module(import_module(fullname, skip_errors=skip_errors),                           docfilter=docfilter, supermodule=self,                           context=self._context, skip_errors=skip_errors)                self.doc[root] = m                # Skip empty namespace packages because they may                # as well be other auxiliary directories                if m.is_namespace and not m.doc:                    del self.doc[root]                    self._context.pop(m.refname)        # Apply docfilter        if docfilter:            for name, dobj in self.doc.copy().items():                if not docfilter(dobj):                    self.doc.pop(name)                    self._context.pop(dobj.refname, None)        # Build the reference name dictionary of the module        self._context[self.refname] = self        for docobj in self.doc.values():            self._context[docobj.refname] = docobj            if isinstance(docobj, Class):                self._context.update((obj.refname, obj)                                     for obj in docobj.doc.values())    class ImportWarning(UserWarning):        """        Our custom import warning because the builtin is ignored by default.        https://docs.python.org/3/library/warnings.html#default-warning-filter        """    __pdoc__['Module.ImportWarning'] = False    @property    def __pdoc__(self) -> dict:        """This module's __pdoc__ dict, or an empty dict if none."""        return getattr(self.obj, '__pdoc__', {})    def _link_inheritance(self):        # Inherited members are already in place since        # `Class._fill_inheritance()` has been called from        # `pdoc.fill_inheritance()`.        # Now look for docstrings in the module's __pdoc__ override.        if self._is_inheritance_linked:            # Prevent re-linking inheritance for modules which have already            # had done so. Otherwise, this would raise "does not exist"            # errors if `pdoc.link_inheritance()` is called multiple times.            return        # Apply __pdoc__ overrides        for name, docstring in self.__pdoc__.items():            # In case of whitelisting with "True", there's nothing to do            if docstring is True:                continue            refname = f"{self.refname}.{name}"            if docstring in (False, None):                if docstring is None:                    warn('Setting `__pdoc__[key] = None` is deprecated; '                         'use `__pdoc__[key] = False` '                         f'(key: {name!r}, module: {self.name!r}).')                if name in self._skipped_submodules:                    continue                if (not name.endswith('.__init__') and                        name not in self.doc and                        refname not in self._context and                        refname not in self._context.blacklisted):                    warn(f'__pdoc__-overriden key {name!r} does not exist '                         f'in module {self.name!r}')                obj = self.find_ident(name)                cls = getattr(obj, 'cls', None)                if cls:                    del cls.doc[obj.name]                self.doc.pop(name, None)                self._context.pop(refname, None)                # Pop also all that startwith refname                for key in list(self._context.keys()):                    if key.startswith(refname + '.'):                        del self._context[key]                continue            dobj = self.find_ident(refname)            if isinstance(dobj, External):                continue            if not isinstance(docstring, str):                raise ValueError('__pdoc__ dict values must be strings; '                                 f'__pdoc__[{name!r}] is of type {type(docstring)}')            dobj.docstring = inspect.cleandoc(docstring)        # Now after docstrings are set correctly, continue the        # inheritance routine, marking members inherited or not        for c in _filter_type(Class, self.doc):            c._link_inheritance()        self._is_inheritance_linked = True    def text(self, **kwargs) -> str:        """        Returns the documentation for this module as plain text.        """        txt = _render_template('/text.mako', module=self, **kwargs)        return re.sub("\n\n\n+", "\n\n", txt)    def html(self, minify=True, **kwargs) -> str:        """        Returns the documentation for this module as        self-contained HTML.        If `minify` is `True`, the resulting HTML is minified.        For explanation of other arguments, see `pdoc.html()`.        `kwargs` is passed to the `mako` render function.        """        html = _render_template('/html.mako', module=self, **kwargs)        if minify:            from pdoc.html_helpers import minify_html            html = minify_html(html)        if not html.endswith('\n'):            html = html + '\n'        return html    @property    def is_package(self) -> bool:        """        `True` if this module is a package.        Works by checking whether the module has a `__path__` attribute.        """        return hasattr(self.obj, "__path__")    @property    def is_namespace(self) -> bool:        """        `True` if this module is a namespace package.        """        try:            return self.obj.__spec__.origin in (None, 'namespace')  # None in Py3.7+        except AttributeError:            return False    def find_class(self, cls: type) -> Doc:        """        Given a Python `cls` object, try to find it in this module        or in any of the exported identifiers of the submodules.        """        # XXX: Is this corrent? Does it always match        # `Class.module.name + Class.qualname`?. Especially now?        # If not, see what was here before.        return self.find_ident(f'{cls.__module__ or _UNKNOWN_MODULE}.{cls.__qualname__}')    def find_ident(self, name: str) -> Doc:        """        Searches this module and **all** other public modules        for an identifier with name `name` in its list of        exported identifiers.        The documentation object corresponding to the identifier is        returned. If one cannot be found, then an instance of        `External` is returned populated with the given identifier.        """        _name = name.rstrip('()')  # Function specified with parentheses        if _name.endswith('.__init__'):  # Ref to class' init is ref to class itself            _name = _name[:-len('.__init__')]        return (self.doc.get(_name) or                self._context.get(_name) or                self._context.get(f'{self.name}.{_name}') or                External(name))    def _filter_doc_objs(self, type: Type[T], sort=True) -> List[T]:        result = _filter_type(type, self.doc)        return sorted(result) if sort else result    def variables(self, sort=True) -> List['Variable']:        """        Returns all documented module-level variables in the module,        optionally sorted alphabetically, as a list of `pdoc.Variable`.        """        return self._filter_doc_objs(Variable, sort)    def classes(self, sort=True) -> List['Class']:        """        Returns all documented module-level classes in the module,        optionally sorted alphabetically, as a list of `pdoc.Class`.        """        return self._filter_doc_objs(Class, sort)    def functions(self, sort=True) -> List['Function']:        """        Returns all documented module-level functions in the module,        optionally sorted alphabetically, as a list of `pdoc.Function`.        """        return self._filter_doc_objs(Function, sort)    def submodules(self) -> List['Module']:        """        Returns all documented sub-modules of the module sorted        alphabetically as a list of `pdoc.Module`.        """        return self._filter_doc_objs(Module)    def _url(self):        url = self.module.name.replace('.', '/')        if self.is_package:            return url + _URL_PACKAGE_SUFFIX        elif url.endswith('/index'):            return url + _URL_INDEX_MODULE_SUFFIX        return url + _URL_MODULE_SUFFIX

Representation of a module's documentation.

Creates aModule documentation object given the actualmodule Python object.

docfilter is an optional predicate that controls whichsub-objects are documentated (see also:html()).

supermodule is the parentModule this module isa submodule of.

context is an instance ofContext. IfNone aglobal context object will be used.

Ifskip_errors isTrue and an unimportable, erroneoussubmodule is encountered, a warning will be issued insteadof raising an exception.

Ancestors

Instance variables

vardoc

A mapping from identifier name to a documentation object.

propis_namespace : bool
Expand source codeBrowse git
@propertydef is_namespace(self) -> bool:    """    `True` if this module is a namespace package.    """    try:        return self.obj.__spec__.origin in (None, 'namespace')  # None in Py3.7+    except AttributeError:        return False

True if this module is a namespace package.

propis_package : bool
Expand source codeBrowse git
@propertydef is_package(self) -> bool:    """    `True` if this module is a package.    Works by checking whether the module has a `__path__` attribute.    """    return hasattr(self.obj, "__path__")

True if this module is a package.

Works by checking whether the module has a__path__ attribute.

varsupermodule

The parentModule this module is a submodule of, orNone.

Methods

defclasses(self, sort=True) ‑> List[Class]
Expand source codeBrowse git
def classes(self, sort=True) -> List['Class']:    """    Returns all documented module-level classes in the module,    optionally sorted alphabetically, as a list of `pdoc.Class`.    """    return self._filter_doc_objs(Class, sort)

Returns all documented module-level classes in the module,optionally sorted alphabetically, as a list ofClass.

deffind_class(self, cls: type) ‑> Doc
Expand source codeBrowse git
def find_class(self, cls: type) -> Doc:    """    Given a Python `cls` object, try to find it in this module    or in any of the exported identifiers of the submodules.    """    # XXX: Is this corrent? Does it always match    # `Class.module.name + Class.qualname`?. Especially now?    # If not, see what was here before.    return self.find_ident(f'{cls.__module__ or _UNKNOWN_MODULE}.{cls.__qualname__}')

Given a Pythoncls object, try to find it in this moduleor in any of the exported identifiers of the submodules.

deffind_ident(self, name: str) ‑> Doc
Expand source codeBrowse git
def find_ident(self, name: str) -> Doc:    """    Searches this module and **all** other public modules    for an identifier with name `name` in its list of    exported identifiers.    The documentation object corresponding to the identifier is    returned. If one cannot be found, then an instance of    `External` is returned populated with the given identifier.    """    _name = name.rstrip('()')  # Function specified with parentheses    if _name.endswith('.__init__'):  # Ref to class' init is ref to class itself        _name = _name[:-len('.__init__')]    return (self.doc.get(_name) or            self._context.get(_name) or            self._context.get(f'{self.name}.{_name}') or            External(name))

Searches this module andall other public modulesfor an identifier with namename in its list ofexported identifiers.

The documentation object corresponding to the identifier isreturned. If one cannot be found, then an instance ofExternal is returned populated with the given identifier.

deffunctions(self, sort=True) ‑> List[Function]
Expand source codeBrowse git
def functions(self, sort=True) -> List['Function']:    """    Returns all documented module-level functions in the module,    optionally sorted alphabetically, as a list of `pdoc.Function`.    """    return self._filter_doc_objs(Function, sort)

Returns all documented module-level functions in the module,optionally sorted alphabetically, as a list ofFunction.

defhtml(self, minify=True, **kwargs) ‑> str
Expand source codeBrowse git
def html(self, minify=True, **kwargs) -> str:    """    Returns the documentation for this module as    self-contained HTML.    If `minify` is `True`, the resulting HTML is minified.    For explanation of other arguments, see `pdoc.html()`.    `kwargs` is passed to the `mako` render function.    """    html = _render_template('/html.mako', module=self, **kwargs)    if minify:        from pdoc.html_helpers import minify_html        html = minify_html(html)    if not html.endswith('\n'):        html = html + '\n'    return html

Returns the documentation for this module asself-contained HTML.

Ifminify isTrue, the resulting HTML is minified.

For explanation of other arguments, seehtml().

kwargs is passed to themako render function.

defsubmodules(self) ‑> List[Module]
Expand source codeBrowse git
def submodules(self) -> List['Module']:    """    Returns all documented sub-modules of the module sorted    alphabetically as a list of `pdoc.Module`.    """    return self._filter_doc_objs(Module)

Returns all documented sub-modules of the module sortedalphabetically as a list ofModule.

deftext(self, **kwargs) ‑> str
Expand source codeBrowse git
def text(self, **kwargs) -> str:    """    Returns the documentation for this module as plain text.    """    txt = _render_template('/text.mako', module=self, **kwargs)    return re.sub("\n\n\n+", "\n\n", txt)

Returns the documentation for this module as plain text.

defvariables(self, sort=True) ‑> List[Variable]
Expand source codeBrowse git
def variables(self, sort=True) -> List['Variable']:    """    Returns all documented module-level variables in the module,    optionally sorted alphabetically, as a list of `pdoc.Variable`.    """    return self._filter_doc_objs(Variable, sort)

Returns all documented module-level variables in the module,optionally sorted alphabetically, as a list ofVariable.

Inherited members

classVariable(name: str,
module: Module,
docstring,
*,
obj=None,
cls: Class | None = None,
instance_var: bool = False,
kind: Literal['prop', 'var'] = 'var')
Expand source codeBrowse git
class Variable(Doc):    """    Representation of a variable's documentation. This includes    module, class, and instance variables.    """    def __init__(self, name: str, module: Module, docstring, *,                 obj=None, cls: Optional[Class] = None, instance_var: bool = False,                 kind: Literal["prop", "var"] = 'var'):        """        Same as `pdoc.Doc`, except `cls` should be provided        as a `pdoc.Class` object when this is a class or instance        variable.        """        super().__init__(name, module, obj, docstring)        self.cls = cls        """        The `pdoc.Class` object if this is a class or instance        variable. If not (i.e. it is a global variable), this is None.        """        self.instance_var = instance_var        """        True if variable is some class' instance variable (as        opposed to class variable).        """        self.kind = kind        """        `prop` if variable is a dynamic property (has getter/setter or deleter),        or `var` otherwise.        """    @property    def qualname(self) -> str:        if self.cls:            return f'{self.cls.qualname}.{self.name}'        return self.name    @property    def refname(self) -> str:        return f'{self.cls.refname if self.cls else self.module.refname}.{self.name}'    def type_annotation(self, *, link=None) -> str:        """Formatted variable type annotation or empty string if none."""        return Function.return_annotation(cast(Function, self), link=link)

Representation of a variable's documentation. This includesmodule, class, and instance variables.

Same asDoc, exceptcls should be providedas aClass object when this is a class or instancevariable.

Ancestors

Instance variables

varcls

TheClass object if this is a class or instancevariable. If not (i.e. it is a global variable), this is None.

varinstance_var

True if variable is some class' instance variable (asopposed to class variable).

varkind

prop if variable is a dynamic property (has getter/setter or deleter),orvar otherwise.

Methods

deftype_annotation(self, *, link=None) ‑> str
Expand source codeBrowse git
def type_annotation(self, *, link=None) -> str:    """Formatted variable type annotation or empty string if none."""    return Function.return_annotation(cast(Function, self), link=link)

Formatted variable type annotation or empty string if none.

Inherited members


[8]ページ先頭

©2009-2025 Movatter.jp