Coder Social home page Coder Social logo

mkdocstrings / mkdocstrings Goto Github PK

View Code? Open in Web Editor NEW
1.6K 14.0 102.0 6.8 MB

:blue_book: Automatic documentation from sources, for MkDocs.

Home Page: https://mkdocstrings.github.io/

License: ISC License

Makefile 0.40% Python 96.02% Shell 3.48% Dockerfile 0.10%
mkdocs mkdocs-plugin python docstrings autodoc mkdocstrings material-theme

mkdocstrings's Introduction

mkdocstrings

ci documentation pypi version conda version gitpod gitter

Automatic documentation from sources, for MkDocs. Come have a chat or ask questions on our Gitter channel.


Features - Installation - Quick usage

mkdocstrings_gif1

Features

  • Language-agnostic: just like MkDocs, mkdocstrings is written in Python but is language-agnostic. It means you can use it with any programming language, as long as there is a handler for it. We currently have handlers for the Crystal, Python, and VBA languages, as well as for shell scripts/libraries. Maybe you'd like to add another one to the list? ๐Ÿ˜‰

  • Multiple themes support: each handler can offer multiple themes. Currently, we offer the :star: Material theme โญ as well as basic support for the ReadTheDocs and MkDocs themes for the Python handler.

  • Cross-references across pages: mkdocstrings makes it possible to reference headings in other Markdown files with the classic Markdown linking syntax: [identifier][] or [title][identifier] -- and you don't need to remember which exact page this object was on. This works for any heading that's produced by a mkdocstrings language handler, and you can opt to include any Markdown heading into the global referencing scheme.

    Note: in versions prior to 0.15 all Markdown headers were included, but now you need to opt in.

  • Cross-references across sites: similarly to Sphinx's intersphinx extension, mkdocstrings can reference API items from other libraries, given they provide an inventory and you load that inventory in your MkDocs configuration.

  • Inline injection in Markdown: instead of generating Markdown files, mkdocstrings allows you to inject documentation anywhere in your Markdown contents. The syntax is simple: ::: identifier followed by a 4-spaces indented YAML block. The identifier and YAML configuration will be passed to the appropriate handler to collect and render documentation.

  • Global and local configuration: each handler can be configured globally in mkdocs.yml, and locally for each "autodoc" instruction.

  • Reasonable defaults: you should be able to just drop the plugin in your configuration and enjoy your auto-generated docs.

Used by

mkdocstrings is used by well-known companies, projects and scientific teams: Ansible, Apache, Google, Jitsi, Microsoft, Prefect, Pydantic, and more...

Installation

With pip:

pip install mkdocstrings

You can install support for specific languages using extras, for example:

pip install 'mkdocstrings[crystal,python]'

See the available language handlers.

With conda:

conda install -c conda-forge mkdocstrings

Quick usage

In mkdocs.yml:

site_name: "My Library"

theme:
  name: "material"

plugins:
- search
- mkdocstrings

In one of your markdown files:

# Reference

::: my_library.my_module.my_class

See the Usage section of the docs for more examples!

mkdocstrings's People

Contributors

bandersen23 avatar cs01 avatar davfsa avatar holt59 avatar huiibuh avatar jaredkhan avatar jdpatt avatar jgarte avatar joerick avatar johnthagen avatar ksneijders avatar lmichaelis avatar mrcurtis avatar ofek avatar ooo-abm avatar oprypin avatar pawamoy avatar percevalw avatar pkoch avatar plannigan avatar rdil avatar ssbarnea avatar ssweber avatar stefanbras avatar stephenbrown2 avatar thatlittleboy avatar velocityra avatar victorbnl avatar waylan avatar willdasilva avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mkdocstrings's Issues

Impossible to run mkdocstrings example

Hi there,
I've been trying to use mkdocstrings, but when I run mkdocs serve this is the error I have:

INFO    -  Building documentation...
INFO    -  Cleaning site directory
ERROR   -  Error reading page 'reference\extension.md': 'WindowsPath' object is not iterable
Traceback (most recent call last):
  File "c:\users\myusername\.conda\envs\prism\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\users\myusername\.conda\envs\prism\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\myusername\.conda\envs\prism\Scripts\mkdocs.exe\__main__.py", line 7, in <module>
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\__main__.py", line 143, in serve_command
    **kwargs
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\commands\serve.py", line 141, in serve
    config = builder()
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\commands\serve.py", line 136, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\commands\build.py", line 274, in build
    _populate_page(file.page, config, files, dirty)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\commands\build.py", line 174, in _populate_page
    page.render(config, files)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocs\structure\pages.py", line 183, in render
    self.content = md.convert(self.markdown)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\markdown\core.py", line 265, in convert
    root = self.parser.parseDocument(self.lines).getroot()
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\markdown\blockparser.py", line 90, in parseDocument
    self.parseChunk(self.root, '\n'.join(lines))
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\markdown\blockparser.py", line 105, in parseChunk
    self.parseBlocks(parent, text.split('\n\n'))
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\markdown\blockparser.py", line 123, in parseBlocks
    if processor.run(parent, blocks) is not False:
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocstrings\extension.py", line 118, in run
    handler = get_handler(handler_name, self._config["theme_name"])
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocstrings\handlers\__init__.py", line 231, in get_handler
    HANDLERS_CACHE[name] = module.get_handler(theme)
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocstrings\handlers\python.py", line 245, in get_handler
    return PythonHandler(collector=PythonCollector(), renderer=PythonRenderer("python", theme))
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\mkdocstrings\handlers\__init__.py", line 124, in __init__
    self.env = Environment(autoescape=True, loader=FileSystemLoader(theme_dir))
  File "c:\users\myusername\.conda\envs\prism\lib\site-packages\jinja2\loaders.py", line 165, in __init__
    self.searchpath = list(searchpath)
TypeError: 'WindowsPath' object is not iterable

My requirements are:
mkdocs==1.1
mkdocs-material==4.6.3
mkdocstrings==0.10.0

Basically, it seems that my searchpath is a WindowsPath type and not a list. But I have no clue how to solve this. Could you help me with this please ?

(I tried to run mkdocs on the mkdocstrings library locally)

Thanks :)

Windows compatibility

On Windows, mkdocs serve fails with the following exception:

ERROR   -  Error reading page 'api\dataset\config.md': list index out of range
Traceback (most recent call last):
  File "c:\users\bennylp\appdata\local\programs\python\python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
...
  File "c:\users\bennylp\appdata\local\programs\python\python37\lib\site-packages\mkdocstrings\renderer.py", line 50, in render_object
    lines.append(f'\n??? note "Show source code in {obj.relative_file_path}"')
  File "c:\users\bennylp\appdata\local\programs\python\python37\lib\site-packages\mkdocstrings\documenter.py", line 190, in relative_file_path
    while path_parts[-1] != file_path_parts[-1]:
IndexError: list index out of range

I think the reason is because the codes in documenter.py does path splitting by '/' character, and this fails on Windows because on Windows the path separator is '\'.

I did a quick and dirty fix by replacing '\' with '/' on all path strings in documenter.py, and I think it works (at least mkdocs serve is serving), but the right solution is to use os.path functions I think.

Issue with wrapper functions

Hey

I have an issue with wrapper functions. Instead of the function that should be documented the wrapper gets displayed in the code preview.
In addition the Notes, Params, ... do not get displayed.

Code:
image

Docs:
image

Error on mkdocs build command

Traceback (most recent call last):
  File "c:\python38\lib\runpy.py", line 193, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\python38\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Python38\Scripts\mkdocs.exe\__main__.py", line 7, in <module>
  File "c:\python38\lib\site-packages\click\core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "c:\python38\lib\site-packages\click\core.py", line 782, in main
    rv = self.invoke(ctx)
  File "c:\python38\lib\site-packages\click\core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\python38\lib\site-packages\click\core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python38\lib\site-packages\click\core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "c:\python38\lib\site-packages\mkdocs\__main__.py", line 159, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "c:\python38\lib\site-packages\mkdocs\commands\build.py", line 274, in build
    _populate_page(file.page, config, files, dirty)
  File "c:\python38\lib\site-packages\mkdocs\commands\build.py", line 177, in _populate_page
    page.content = config['plugins'].run_event(
  File "c:\python38\lib\site-packages\mkdocs\plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "c:\python38\lib\site-packages\mkdocstrings\plugin.py", line 160, in on_page_content
    self.map_urls(page.canonical_url, item)
  File "c:\python38\lib\site-packages\mkdocstrings\plugin.py", line 173, in map_urls
    self.url_map[anchor.id] = base_url + anchor.url
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

The error doesn't happen with mkdocs serve.

Allow setting default handler options in top keys of plugins.mkdocstrings in mkdocs.yml

Currently, to define global selection and rendering for the Python handler, one has to write:

plugins:
  - mkdocstrings:
      handlers:
        python:
          selection:
            filters:
              - "!^_[^_]"
          rendering:
            option1: etc

Since we have a default_handler option, we could support setting selection and rendering like this:

plugins:
  - mkdocstrings:
      selection:
        filters:
          - "!^_[^_]"
      rendering:
        option1: etc

In this case, since the default default_handler is Python, these options apply for it.

With

plugins:
  - mkdocstrings:
      default_handler: rust
      selection:
        option1: etc
      rendering:
        option1: etc

...they would apply for the Rust handler.

AttributeError: type object 'int' has no attribute '__getitem__'

When runnning mkdocs serve I've got the following error:

  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/plugin.py", line 49, in on_nav
    root_object = self.documenter.get_object_documentation(import_string)
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 306, in get_object_documentation
    root_object = self.get_class_documentation(obj, module)
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 363, in get_class_documentation
    if RE_SPECIAL.match(member_name) and docstring == inspect.getdoc(getattr(int, member_name)):
AttributeError: type object 'int' has no attribute '__getitem__'

Environment: python 3.7.5

mkdocs.yml:

repo_url: https://github.com/maxsch3/keras-batchflow/
theme: readthedocs

plugins:
- mkdocstrings

markdown_extensions:
  - admonition
  - codehilite
  - attr_list
  - pymdownx.details
  - pymdownx.superfences
  - pymdownx.inlinehilite

nav:
  - Home: index.md
  - User guide: user_guide.md
  - Examples: examples.md
  - API: reference.md

Use git tags for releases, update CHANGELOG

I'm enjoying the work so far, but it's a bit hard to follow the progress, as there are no releases on GitHub, and no tags in lieu of "official" releases.

Could you perhaps start tagging releases with the version number and pushing them to GitHub? Oh, and also update the CHANGELOG.md? I realize it's difficult sometimes when you're working stream-of-consciousness as I often do.

Decorated functions ignored

This is similar to a topic documented in your troubleshooting guide, but not precisely. In this case, I'm using the Python builtin @[property_name].setter decorator to set a property, but this docstring is ignored by mkdocstrings. In fact, that property of the class I am documenting is not registered at all, even when explicitly selected with

    selection:
      members:
        - property_name

EDIT: This property will show up like
property_name property writable
with no docstring if I set show_if_no_docstring: true

I would be happy to try to fix this, if you can point me in the right direction.

Thanks!

Not compatible with python 3.7

Python 3.7.5

mkdocs.yml:

site_name: Keras batchflow
repo_url: https://github.com/maxsch3/keras-batchflow/
theme: readthedocs

plugins:
- mkdocstrings

nav:
  - Home: index.md
  - User guide: user_guide.md
  - Examples: examples.md

mkdocs serve

  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocs/config/config_options.py", line 580, in load_plugin
    Plugin = self.installed_plugins[name].load()
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/__init__.py", line 10, in <module>
    from .plugin import MkdocstringsPlugin
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/plugin.py", line 6, in <module>
    from .documenter import Documenter
  File "/home/max/Code/opensource/batchflow/venv/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 12, in <module>
    from typing import Any, Callable, Dict, GenericMeta, List, Optional, Pattern, Tuple, Type, Union
ImportError: cannot import name 'GenericMeta' from 'typing' (/usr/lib/python3.7/typing.py)

Looks like GenericMeta has been removed from python specification https://www.python.org/dev/peps/pep-0560/

I found a link where people suggest the following fix:

try:
    from typing import GenericMeta  # python 3.6
except ImportError:
    # in 3.7, genericmeta doesn't exist but we don't need it
    class GenericMeta(type): pass

Functions with `*` (Keyword-Only Arguments) notation render `*` between each arg

https://www.python.org/dev/peps/pep-3102/ allows for a * to delineate the following arguments as keyword-only, meaning they cannot be called positionally, even if they have no default value.

However, with mkdocstrings/pytkdocs, it seems the star is added between each argument. e.g.:

async def get_exceptions(
    self, *, calendar_id: int, start_date: pendulum.Date, end_date: pendulum.Date
) -> typing.Dict:

renders as

Screenshot 2020-03-30 at 10 00 38

Feel free to move this issue to pytkdocs if it's more suited to be there.

Allow configurable top heading level

Currently my interface documentation has a primary class, with subclasses created as attributes on init. In order to document them logically, I've organized the api.md as:

# MainClass

::: library.MainClass

## MainClass.sub_class_a

::: library.package.module.SubClassA

## MainClass.sub_class_b

::: library.package.module.SubClassB

However, the header value is only 1 or two, dependent on "show_top_level_heading": https://github.com/pawamoy/mkdocstrings/blob/28f0e4279966ff14b2c4e96adc8a6753acc03e20/src/mkdocstrings/plugin.py#L93

I would like to set it to 3, perhaps with a start_heading_level config option. This and the other config options should be exposed to the user, but that will probably come later as this project matures.

Discover package's submodules

When using ::: mypackage, we should automatically discover and build the documentation data for every submodule of mypackage.

Something like

import pkgutil

# this is the package we are inspecting -- for example 'email' from stdlib
import email

package = email
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__):
    print "Found submodule %s (is a package: %s)" % (modname, ispkg)

from https://stackoverflow.com/questions/1707709/list-all-the-modules-that-are-part-of-a-python-package

Auto-register required extensions + opt-out option

Instead of asking the user to add many extension in their config file, we could automatically add them from the on_config event. However we should allow the user to keep control of the extensions, with an opt-out configuration option.

Void built-in docstrings

When listing the objects in a class __dict__, we always get the __init__ method, which have a pre-populated docstring: Initialize self. See help(type(self)) for accurate signature.. Same for most (or all) of the other special methods (__str__, __repr__, etc.)

We should detect when the docstring is the built-in one, and wipe it, because surely the user does not want to render it.

A simple way to check that is something like

if docstring == inspect.getdoc(int.__str__):
    # discard it
# or
if docstring == inspect.getdoc(int.__init__):
    # discard it

Contributing

Some of you shown interest in contributing to this project, and others already contributed ๐Ÿ™‚!

I really, really appreciate it! Thank you all very much.

As stated in other comments, I have a full-time job now so I can only give so much of my time to this project. This issue is here to discuss how the community can contribute to this project. I don't have any experience in leading/managing/guiding an open-source community, so I'll try my best to help you help me ๐Ÿ™‚

EDIT: new architecture is released (#28). I'll update this post accordingly.

Now, there are some things that you could help with, and I'll try to list them here:

  • Jinja templates!

    I wrote the ones to render Python documentation for the Material theme, but it would be great to have templates for the built-in themes of mkdocs. You have full freedom but should obviously match the style of the themes.

  • A proper "Google-style docstrings" Markdown extension.

    EDIT: not sure about this anymore. A robust docstring parser in pytkdocs is fine as well. It has some limitations but some benefits as well. End of edit.

    Currently, docstrings parsing is done in pytkdocs. It returns structured data for parameters, return types, raw markdown blocks, etc., but it's not optimal as it puts limitations on how the docstrings can be written, and makes it harder to render them.

    The best would be to have this "google-style docstring" markdown extension that we could use from inside the templates, as a jinja filter, to render a complete, raw docstring directly. It would be very similar to the admonition extension in how it parses the blocks: instead of !!! type "Title", it would match Type: Title and then the underlying indented block. Special handling would be done for Arguments:, Returns:, etc. titles, otherwise treat them as simple admonitions (Important:, Note:, etc.).

    It could be a bit challenging: how to pass the signature data? This will need discussion.

    It should also be able to render Jinja templates to allow mkdocstrings and the final users to override how the docstrings are rendered. Maybe later it should not require Jinja as a dependency, and have a hardcoded render format, so people can use the extension outside of mkdocstrings.

  • Documentation collectors for other languages, and/or their respective handlers in mkdocstrings, similarly to the python handler using pytkdocs. Check out how the Python handler is implemented: https://pawamoy.github.io/mkdocstrings/reference/handlers/python

I created a Gitter community so we can discuss all this, as I couldn't give all the details here.

Refactor

The code is ugly ๐Ÿคข

Ideally, we would use the same approach as mkautodoc: with a Markdown extension.

  • we would directly manipulate an HTML tree (much, much cleaner)
  • we could get rid of the markdown extensions requirements

But:

  • there's no easy way to automatically register an extension from a plugin (or is there? mkdocs/mkdocs#1942)
  • we would need to change the object references logic (currently in two passes: on_nav builds all objects and references, on_page_markdown appends all references to all pages containing autodoc instructions). Using a markdown extension, we would need to pass information from the plugin to the extension (the objects references), and I'm not sure if this is easy or even possible (see previous point).
  • we would maybe need to import codehilite, inlinehilite and other functions to replicate the related and currently required markdown extensions

General improvements to do:

  • be more robust: catch exceptions, log warnings and fail gracefully when information is missing (types, annotations, etc.) or not in the right format (parameters types in docstrings, etc.)
  • refactor type/annotation related functions: there are currently a few functions to get the return type, the parameters type, the signature, etc. It could be way more compact and elegant.
  • use subclasses for the different objects categories: Function, Method, Attribute, Module and Class. Probably Type (name + path for automatic reference), Parameter (name + type + description + default), Return (type + description) and Exception (type + description) as well (find another name for Exception hehe)

Ideally we would still proceed in two steps:

  1. build all the necessary data in the on_nav event
  2. render it directly to HTML with a markdown extension having access to the data

`mkdocs serve` does not watch for changes in mkdocstrings

Usually when I view mkdocs-generated documenation during development, the server will watch for changes and the page will auto-reload when changes are detected. Using mkdocstrings, I have not seen this happening, and to view changes I have to kill the mkdocs serve process and restart it.

Recursive discovery of objects

We currently pick:

  • all modules within a package
  • all classes and functions within a module
  • all classes and methods within a class
  • all documented attribute declared in a file, including in __init__ methods (no other method/function)

Maybe we should pick more? What are the potential use-cases?

This issue is here to discuss about that.

TOC broken when selecting non-modules

# API

-----

::: datadog_checks.base.AgentCheck
    selection:
      members:
        - gauge
        - count
        - monotonic_count
        - rate
        - histogram
        - historate
        - service_check
        - event

::: datadog_checks.base.stubs.aggregator.AggregatorStub
    selection:
      members:
        - assert_metric
        - assert_metric_has_tag
        - assert_metric_has_tag_prefix
        - assert_service_check
        - assert_event
        - assert_all_metrics_covered
        - assert_no_duplicate_metrics
        - assert_no_duplicate_service_checks
        - assert_no_duplicate_all
        - reset

::: datadog_checks.base.stubs.datadog_agent.DatadogAgentStub

Capture

Autodoc enums

Allow autodoc to parse enums:

class MyEnum(enum.Enum):
    OPTION1 = "text"  #: Some PEP says this is a valid docstring
    OPTION2 = "other text"  #: This also!  

Module 'bot' not found.

Hello. Trying to use your plugin in my bot's documentation. And i can't understand, what folders i should watch. Here is my project's structure:
Screenshot_20200409_140836

Here is my mkdocstrings' config:

    - mkdocstrings:
        default_handler: python
        handlers:
            python:
            rendering:
                show_source: true
    - watch:
        - bot
        - ../bot

Here is content of .md file:

::: bot.keyboards

And it produces this error:

ERROR   -  mkdocstrings.handlers.python: Collection failed: No module named 'bot'
Traceback (most recent call last):
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/loader.py", line 133, in get_object_tree
    parent_module = importlib.import_module(parent_module_path)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'bot'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/cli.py", line 179, in main
    print(json.dumps(process_json(line)))
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/cli.py", line 116, in process_json
    return process_config(json.loads(json_input))
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/cli.py", line 93, in process_config
    obj = loader.get_object_documentation(path, members)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/loader.py", line 205, in get_object_documentation
    leaf = get_object_tree(dotted_path)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/pytkdocs/loader.py", line 136, in get_object_tree
    raise ImportError("No module named '%s'" % obj_parent_modules[0])
ImportError: No module named 'bot'
 
ERROR   -  mkdocstrings.extension: Could not collect 'bot.keyboards' 

How can i import contain of bot module and root of the project?

TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

Describe the bug
mkdocs build (runned from directory with its config) raises this error

ERROR   -  Error reading page 'index.md': unsupported operand type(s) for +: 'NoneType' and 'str' 
Traceback (most recent call last):
  File "/home/dadyarri/projects/bjorn/venv_bjorn/bin/mkdocs", line 10, in <module>
    sys.exit(cli())
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocs/__main__.py", line 159, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocs/commands/build.py", line 274, in build
    _populate_page(file.page, config, files, dirty)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocs/commands/build.py", line 177, in _populate_page
    page.content = config['plugins'].run_event(
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocstrings/plugin.py", line 160, in on_page_content
    self.map_urls(page.canonical_url, item)
  File "/home/dadyarri/projects/bjorn/venv_bjorn/lib/python3.8/site-packages/mkdocstrings/plugin.py", line 173, in map_urls
    self.url_map[anchor.id] = base_url + anchor.url
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

index.md:

# Bjorn

[![MIT License](https://img.shields.io/pypi/l/aiogram.svg?style=flat-square)](https://opensource.org/licenses/MIT)
[![Telegram Bot API](https://img.shields.io/badge/Telegram%20Bot%20API-4.7-blue.svg?style=flat-square&logo=telegram)](https://core.telegram.org/bots/api)

Bot-helper for students groups written with [aiogram](https://aiogram.dev)

Docs for {{ version() }} [WIP]

## ะคัƒะฝะบั†ะธะพะฝะฐะป

- [Call](functions/call.md)
- [Mailings](functions/mailings.md)
- [Finances](functions/finances.md)
- [Schedule](functions/schedule.md)
- [Preferences](functions/preferences.md)

Expected behavior
No exception

Information (please complete the following information):

  • OS: Manjaro linux
  • Browser: Brave
  • mkdocstrings 0.10.2

Nested Classes

Currently nested classes are note supported my mkdocstrings.

image

image

Add source code display for modules

I'm currently testing generating documentation for pytkdocs test suite.

For fixtures, it would be better to show the module's docstring and source code, and not show any of its members.

(Selection of members is discussed in #44)

Currently the templates do not even try to show the source code for a module. pytkdocs will need to pick up the source code of whole modules as well.

Type error in plugin.py

This is the error I'm getting trying to run mkdocs build. I had everything working in a previous version (prior to removal of documenter.py).

C:\Users\u609587\Desktop\oompa>mkdocs build
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: C:\Users\u609587\Desktop\oompa\site
ERROR   -  Error reading page 'index.md': unsupported operand type(s) for +: 'NoneType' and 'str'
Traceback (most recent call last):
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\u609587\AppData\Local\Continuum\anaconda3\Scripts\mkdocs.exe\__main__.py", line 9, in <module>
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\click\core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\click\core.py", line 717, in main
    rv = self.invoke(ctx)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\click\core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\click\core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\click\core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocs\__main__.py", line 159, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocs\commands\build.py", line 274, in build
    _populate_page(file.page, config, files, dirty)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocs\commands\build.py", line 178, in _populate_page
    'page_content', page.content, page=page, config=config, files=files
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocs\plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocstrings\plugin.py", line 160, in on_page_content
    self.map_urls(page.canonical_url, item)
  File "c:\users\u609587\appdata\local\continuum\anaconda3\lib\site-packages\mkdocstrings\plugin.py", line 173, in map_urls
    self.url_map[anchor.id] = base_url + anchor.url
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

This is what index.md looks like:

# Welcome to OOMPA Documentation

This site documents the OOMPA Library.

Supported model classes:

- [Error Correction / Auto Regressive Distributed Lag](ardl.md)
- [Double/Debiased Machine Learning](dml.md)

Supporting utilities and superclasses:

- [Comments](comment.md)
- [Pandas Extras](pandas_extras.md)

any advice?

Methods without a docstring do not get rendered

Setup

mkdocstrings version 0.10.0
Python 3.8.1
Windows 10

Description

This

::: datadog_checks.base.stubs.datadog_agent.DatadogAgentStub

renders this

https://github.com/DataDog/integrations-core/blob/hack-a-doc/datadog_checks_base/datadog_checks/base/stubs/datadog_agent.py#L6

as nothing:

<h6 class=hidden-toc href=#datadog_checks.base.stubs.datadog_agent.DatadogAgentStub id=datadog_checks.base.stubs.datadog_agent.DatadogAgentStub style="visibility: hidden; width: 0; height: 0;"> <a class=headerlink href=#datadog_checks.base.stubs.datadog_agent.DatadogAgentStub title="Permanent link">ยถ</a></h6>

If I add a class docstring then I get the text but the anchor is still hidden (and no members of course b/c no docstrings).

I'd expect the linked code to look something like we have here (with https://github.com/tomchristie/mkautodoc):

https://datadoghq.dev/integrations-core/base/api/#datadog-agent

Enhancement: Separate Properties and class variables

At the moment properties and class variables are mixed in the documentation.
I think a setting which separates properties and class variables would be nice.
Class Variables and properties could be grouped which would make the reading of the documentation a bit easier.

image

Architecture

Introduction

This document describes the different ways mkdocstrings can be implemented, their advantages and disadvantages.

The two main ways are:

  • as an Mkdocs plugin only
  • as an Mkdocs plugin plus a Markdown extension

What's a plugin?

An Mkdocs plugin is a set of methods called when certain events happen.

There are three kinds of events:

  • global events, called once per build, at either the beginning or end of the build process;
  • template events, called once for each non-page template (Jinja2/HTML files), all called after the on_env event and before any page event;
  • page events, called once per Markdown page included in the site, all called after the post_template and before the post_build event.

The events used in mkdocstrings are:

  • on_config: global event, used to prepare the configuration of the plugin
  • on_serve: global event, used to add (source) directories to watched paths
  • on_nav: global event, used to find "autodoc" instructions and pre-build documentation for every page
  • on_page_markdown: page event, used to append Python objects references to allow cross-linking
  • on_page_contents: page event, used to insert HTML divs to allow styling

When developing the plugin, we have to keep in mind that other plugins' hooks on events can be called before or after mkdocstrings' own hooks.

architecture drawio-0

Maybe you find it easier to understand a flow with pseudo-code? It should be something like this:

config = run_event_on_config(initial_config)
server = run_event_on_serve(initial_server, config)
nav = run_event_on_nav(initial_nav)

for page in nav.pages:
    page.markdown = run_event_on_page_markdown(page.raw_text, page)
    page.html = markdown.convert(page.markdown, config.extensions)

for page in nav.pages:
    page.html = run_event_on_page_contents(page.html, page)

config.theme.render(nav)

What's a Markdown extension?

For our use-case, we can describe a Markdown extension as: "a piece of code that is triggered when a markdown block matches its regular expression, and that renders a Python object's documentation to HTML".

Typically, the goal here would be to match our "autodoc" instructions, whatever their format is, and render the corresponding object documentation instead of the instruction.

Example:

## My func

::: lib.mod.func

Our Markdown extension would match the ::: * line, and render documentation for the Python object lib.mod.func, directly to HTML.

A concrete implementation can be found in mkautodoc on GitHub (mkdocstrings was inspired from mkautodoc, thank you @tomchristie!)

Working as a plugin only

When working as a plugin only, mkdocstrings can (help) generate the final output in several ways.

"Normal-flow"

In the on_page_markdown event, replace "autodoc" instructions with Markdown generated from the documentation.

Advantage: straight-forward, follow the logical flow of transformation.

Disadvantage: Markdown extensions required by mkdocstrings must be registered by the user in mkdocs.yml, or automatically inserted in the config from the on_config event. These extensions are used globally, for every page, which might not be what the user wants.

"Discard-and-re-render"

For pages containing "autodoc" instructions, discard the rendered HTML in on_page_contents, and use the original markdown again (from page.markdown parameter) to convert it through a local Markdown converter instance.

Advantage: using a local Markdown converter allows us to use whatever extension we require, combined to the user-specified extensions, to render the markdown to HTML. User does not have to register these extensions in mkdocs.yml anymore, and they do not affect other pages. Absolute URLs of cross-references can be appended only once, at the end of the Markdown text.

Disadvantage: mkdocstrings can lose compatibility with other plugins, in certain conditions: the other plugins modify HTML in on_page_contents before mkdocstrings. In that case, mkdocstrings will discard these modifications, and they will be lost.

"Direct-HTML"

In the on_page_contents event, replace "autodoc" instructions (of the form <p>INSTRUCTION</p>) with HTML generated from the documentation.

Advantage: generating HTML directly allows us to get rid of Markdown extensions requirements. HTML generation using an XML tree seems cleaner than concatenating lots of Markdown lines and then inserting divs in the output. It also allows more flexibility in the output (each element can have its own CSS classes), and therefore allows finer CSS styling by the user.

Disadvantage: the Table Of Contents must be updated manually, as it's computed while converting Markdown to HTML. We must imitate the HTML that Markdown extensions are generating, either manually or by importing some logic from their code. We also still need to convert docstrings (which are written in Markdown) to HTML using a Markdown converter. References to other Python objects must all be appended to each and every docstring to make sure links are correctly rendered.

Working as a plugin plus Markdown extension

We add a Markdown processor that is responsible for rendering "autodoc" instructions to HTML.

Advantages: we do not have to update the Table Of Contents manually. "Autodoc" instructions are rendered in complete isolation: the rest of the Markdown is not affected by mkdocstrings. Complete flexibility, allowing CSS customization. We don't have to insert divs in the on_page_contents even anymore.

Disadvantages: the extension must imitate the other extensions we get rid of, either manually or by importing some of their code, append all objects references to every docstring, and convert them from Markdown to HTML.

Final note

The "direct HTML" and "plugin+extension" methods are more complex to write and maintain, but allow more customization. They do not require the user to add extensions to the config, but would probably depend on them (Python imports). The extension is preferred to the "direct HTML" since they are implemented the same but the latter requires to update the TOC of each page manually.

The "discard" method is transparent for the user, and only modifies extensions for pages containing "autodoc" instructions. However, it can be incompatible with other plugins modifying HTML, and should therefore be put first in the list of plugins.

The "normal flow" either requires the user to add extensions in the config, or automatically adds them. These extensions are global and affect every page.

Overall, the best solution probably is the extension, as it allows complete customization of the output and works in isolation of the rest of the Markdown contents (no side-effects).

The second best solution is one of "normal flow" and "discard", depending on what users think is better: 100% compatibility with other plugins or partial isolation of the Markdown to HTML conversion (possible side-effects only in pages containing "autodoc" instructions).

The worst solution is the "direct HTML" rendering (plugin only) as it only has disadvantages over the "extension" one.

Replace `_empty` with `` in the `Type` column

Right now if a type annotation is not present, it's rendered as _empty. It should just be an empty table cell if there is no type, otherwise it looks like it's using a type called _empty. It could also say "unknown" or "not defined".

0.10.1 won't install with latest pymdown-extensions

Docstrings of parent methods

How would I render docstrings of methods inherited from a parent class?

To try this out, here is a minimal example for which I'd have expected parent_method to show up as part of the test.Child docstring:

# test.py

class Parent:
    def parent_method(self, arg):
        """Parent method
        
        Args:
            arg: Arg
        """

class Child(Parent):
    def child_method(self, arg):
        """Child method
        
        Args:
            arg: Arg
        """
# index.md

::: test.Child
    selection:
      members:
        - child_method
        - parent_method

Code block are not rendered inside admonition block

I used to be able to define code in admonition blocks in my docstring and they were correctly displayed in my documentation:

Screenshot from 2020-04-01 11-53-13

But since version 0.9.0, code blocks seem to be problematic:

Screenshot from 2020-04-01 11-54-02

The problem seems to come from the extra indentation needed in the admonition blocks:

"""
Analogs DataArray with `axis`, `channel` and `time_frame` dimensions.

Arguments:
    data: Array to be passed to xarray.DataArray
    channels: Channel names
    time_frames: Time vector in seconds associated with the `data` parameter
    args: Positional argument(s) to be passed to xarray.DataArray
    kwargs: Keyword argument(s) to be passed to xarray.DataArray

Returns:
    Analogs `xarray.DataArray` with the specified data and coordinates

!!! example
    To instantiate an `Analogs` with 4 channels and 100 frames filled with some random data:

    ```python
    import numpy as np
    from motion import Analogs

    n_channels = 4
    n_frames = 100
    data = np.random.random(size=(n_channels, n_frames))
    analogs = Analogs(data)
    ```

    You can add the channel names:

    ```python
    names = ["A", "B", "C", "D"]
    analogs = Analogs(data, channels=names)
    ```

    And an associate time vector:

    ```python
    rate = 100  # Hz
    time_frames = np.arange(start=0, stop=n_frames / rate, step=1 / rate)
    analogs = Analogs(data, channels=names, time_frames=time_frames)
    ```

!!! note
    Calling `Analogs()` generate an empty array.
"""

Do you have an idea how to solve this problem?

Keep up the good work. You've definitely made documentation easier!

Configuration for pytkdocs `filter` option?

I see that pytkdocs has a single configuration option, though it's unclear where I can set that helpful regex in the mkdocs.yml under mkdocstrings. I've got a special class function that I don't really want in the generated docs.

AnchorLink TypeError

If you run into this error:

...
File "/path/to/venv/lib/python3.7/site-packages/mkdocs/structure/toc.py", line 59, in _parse_toc_token
    anchor = AnchorLink(token['name'], token['id'], token['level'])
TypeError: string indices must be integers

The solution is to temporarily pin your version of mkdocs to 1.0.4.

I will soon release version 0.8.0 that will be compatible with mkdocs 1.1 (but not compatible anymore with mkdocs < 1.1, unless someone can advise me on how to support both!).

Strange error

Getting this:

ERROR   -  Error reading page 'libraries/filehandlers/api.md': list index out of range 
Traceback (most recent call last):
  File "/workspace/.pip-modules/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/__main__.py", line 134, in serve_command
    livereload=livereload
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 119, in serve
    config = builder()
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 114, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/build.py", line 274, in build
    _populate_page(file.page, config, files, dirty)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/build.py", line 181, in _populate_page
    'page_content', page.content, page=page, config=config, files=files
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/plugin.py", line 138, in on_page_content
    modified_lines[i] = "\n".join(renderer.render(root_object, heading))
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 27, in render
    self.render_object(obj, heading_level, lines)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 59, in render_object
    self.render_categories(obj, heading_level + 1, lines)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 80, in render_categories
    self.render_object(method, heading_level + extra_level, lines)
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 50, in render_object
    lines.append(f'\n??? note "Show source code in {obj.relative_file_path}"')
  File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 190, in relative_file_path
    while path_parts[-1] != file_path_parts[-1]:
IndexError: list index out of range

"Show source code in..." should be more subtle

When viewing documentation, I rarely/never want to look at the underlying source code. Assuming the majority of use cases is to not view source, the visual real estate for the "Show source..." button should be smaller.

Python 3.7+: cannot import name 'GenericMeta' from 'typing'

When attempting to run with mkdocstrings in a python 3.7 venv, I got the following traceback:

Traceback (most recent call last):
  File "/path/to/repo/.nox/docs/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/__main__.py", line 162, in build_command
    site_dir=site_dir
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/base.py", line 197, in load_config
    errors, warnings = cfg.validate()
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/base.py", line 107, in validate
    run_failed, run_warnings = self._validate()
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/base.py", line 62, in _validate
    self[key] = config_option.validate(value)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/config_options.py", line 132, in validate
    return self.run_validation(value)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/config_options.py", line 572, in run_validation
    plgins[item] = self.load_plugin(item, cfg)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocs/config/config_options.py", line 580, in load_plugin
    Plugin = self.installed_plugins[name].load()
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocstrings/__init__.py", line 10, in <module>
    from .plugin import MkdocstringsPlugin
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocstrings/plugin.py", line 6, in <module>
    from .documenter import Documenter
  File "/path/to/repo/.nox/docs/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 12, in <module>
    from typing import Any, Callable, Dict, GenericMeta, List, Optional, Pattern, Tuple, Type, Union
ImportError: cannot import name 'GenericMeta' from 'typing' (/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/typing.py)

A quick Google tells me that GenericMeta is no longer in Python 3.7, and a workaround is:

try:
    from typing import GenericMeta  # python 3.6
except ImportError:
    # in 3.7, genericmeta doesn't exist but we don't need it
    class GenericMeta(type): pass

How do I run mkdocstrings

Hey I am sorry if this is a stupid question, but how do I run mkdocstrings?
Typing mkdocstrings into the terminal only leads to an error...

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.