Git Product home page Git Product logo

mkapi's People

Contributors

ahrak avatar daizutabi avatar simbuerg avatar timvink avatar tony 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

Watchers

 avatar  avatar

mkapi's Issues

ValueError: Could not find object: <package_name>

I have installed mkapi via pip.

I am trying to use page mode as per the documentation.

My mkdocs.yml has

# multiple lines not here for brevity
nav:
  - API: mkapi/api/wappdriver
plugins:
  - mkapi:
        src_dirs: ['wappdriver']

Here wappdriver is the name of my package.

The directory structure is like:

- mkdocs.yml
- setup.py
- wappdriver
   - __init__.py
   - module.py
- docs
    - index.md

When I run mkdocs serve

I get the following error

INFO    -  Building documentation... 
Traceback (most recent call last):
  File "/home/linuxbrew/.linuxbrew/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/__main__.py", line 133, in serve_command
    serve.serve(
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 141, in serve
    config = builder()
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 136, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/build.py", line 236, in build
    config = config['plugins'].run_event('config', config)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/mkdocs.py", line 50, in on_config
    config, self.abs_api_paths = mkapi.plugins.api.create_nav(
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/api.py", line 23, in create_nav
    page[key], abs_api_paths_ = collect(
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/api.py", line 47, in collect
    module = get_module(package_path)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/core/module.py", line 96, in get_module
    obj = get_object(name)
  File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/core/object.py", line 39, in get_object
    raise ValueError(f"Could not find object: {name}")
ValueError: Could not find object: wappdriver

Is my way of usage of page mode incorrect ? Could you please guide if so.

Many thanks for reading. Your help is most appreciated.

Exception thrown when coming across `Tuple[str, ...]`

Tuple supports an undefined number of entries with ... but an exception gets thrown when processing ...

  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 270, in get_attributes
    return get_class_attributes(obj)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 186, in get_class_attributes
    attr_lineno = get_attributes_with_lineno(nodes, module)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 121, in get_attributes_with_lineno
    attr, lineno, type_str = parse_annotation_assign(x)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 61, in parse_annotation_assign
    type = parse_node(assign.annotation)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 47, in parse_node
    return parse_subscript(x)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 27, in parse_subscript
    slice = ", ".join(slice)
TypeError: sequence item 1: expected str instance, ellipsis found

In

def parse_subscript(x) -> str:
    value = parse_node(x.value)
    slice = parse_node(x.slice.value)
    if isinstance(slice, str):
        return f"{value}[{slice}]"
    else:
        slice = ", ".join(slice)
        return f"{value}[{slice}]"

Short filter for nav items in page mode

I am using mkapi in Page mode to build an API reference for my package, which looks like this:

image

Using the material theme, this is also completely unreadable as the entries get cropped at the important information.
So I was wondering if there is already a feature similar to the |short filter for headlines that can be applied to the navigation items, so that it strips the root package name (in my case tgintegration) from all nav items...

I can't help but think that the following function is actually responsible for doing this, so maybe I'm running into a bug or haven't turned on a feature that I missed in the docs:

def clear_prefix(toc, level: int, id: str = ""):
for toc_item in toc:
if toc_item.level >= level and (not id or toc_item.title == id):
toc_item.title = toc_item.title.split(".")[-1]
clear_prefix(toc_item.children, level)
return

Is there a way to interject the menu item generator and add this myself?

Pypi package does not include `templates` and `theme` folders

Hi,

It seems that the package distributed through pypi does not include templates folder which produces an error in mkdocs:

(.venv) mkdocs serve
INFO    -  Building documentation...

[WinError 3] The system cannot find the path specified: 'c:\\users\\my.user\\devel\\rics\\pi_lib\\.venv\\lib\\site-packages\\mkapi\\templates'

I installed it via pip install mkapi (version 0.4.0)

Placing the templates folder in the module path works like a charm.
Also, not sure if needed but the theme folder isn't distributed either.

pip install mkapi not working

When running pip install mkapi:

Could not find a version that satisfies the requirement mkapi (from versions: )
No matching distribution found for mkapi

Is supporting Numpy docstring possible?

Hi,

I really like this project and how the documentation is rendered.
Is there any plan to extend this plugin to support the Numpy Doctring, as this is very commonly used?

Thanks and regards,

Inherited methods not showing if base class in different file

Hi,

First, thanks a lot for all those recent improvements in mkapi, it is impressive!

Upgrading to mkapi 0.7.6 from 0.5.0, it seems that now the inherited methods are not showing up if the base class is in a different file.

Code to reproduce:
test.py:

from mixin_ext import MixinExt


class Mixin2:
    def method_mixin2(self, c: int):
        """ Doc method_mixin2 defined in same file"""
        pass


class SubClass(MixinExt, Mixin2):
    def __init__(self, string_a: str):
        pass

    def method_class(self, a: int):
        """ Docstring method_class """
        pass

and mixin_ext.py:

class MixinExt:
    def method_mixin_ext(self, b:int):
        """ Doc method mixin defined external file"""
        pass

If we then try to have ![mkapi](test.SubClass) in the doc, it will only show:
test
Nothing is shown about method_mixin_ext inherited from the MixinExt Class...
The page mode is also impacted.
It was working as expected in 0.5.0.

Thanks

plugin not installed and API docs pages exist but not in nav

Versions:
python 3.8.0
mkapi 1.0.14
mkdocs 1.1.2

Issue:

(django-admin-confirm-3.8.0) thu@Thus-MBP django-admin-confirm % python -m mkdocs build
Module('admin_confirm.admin', num_sections=0, num_members=2)
INFO    -  Cleaning site directory 
INFO    -  Building documentation to directory: /Users/thu/code/django-admin-confirm/site 
INFO    -  The following pages exist in the docs directory, but are not included in the "nav" configuration:
  - api/admin_confirm.admin.md
  - api/source/admin_confirm.admin.md 
[I 210225 09:25:58 watcher:110] Running task: builder (delay: None)
INFO    -  Running task: builder (delay: None)
INFO    -  Building documentation... 
ERROR   -  Config value: 'plugins'. Error: The "mkapi" plugin is not installed 

It also had issues with when nav was not listed in the yml.

This is my config:

site_name: My Docs
theme: readthedocs
plugins:
  - search
  - mkapi
nav:
  - index.md
  - API: mkapi/api/admin_confirm

If I just do build it sometimes kinda works (doesn't add nav correctly):

python -m mkdocs build          
Module('admin_confirm.admin', num_sections=0, num_members=2)
INFO    -  Cleaning site directory 
INFO    -  Building documentation to directory: /Users/thu/code/django-admin-confirm/site 
INFO    -  The following pages exist in the docs directory, but are not included in the "nav" configuration:
  - api/admin_confirm.admin.md
  - api/source/admin_confirm.admin.md 
INFO    -  Documentation built in 0.75 seconds 

But serve has the same problem as above.

[BUG] Exception on document generation

mkapi can crash for some specific classes on document generation.
Exception gets thrown in core/docstring.py:194 and core/object.py:133:

ERROR - Error reading page 'api\prettyqt.custom_widgets.promptlineedit.md': descriptor 'mro' of 'type' object needs an argument Traceback (most recent call last): File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "c:\python37\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python37\Scripts\mkdocs.exe\__main__.py", line 7, in <module> File "c:\python37\lib\site-packages\click\core.py", line 829, in __call__ return self.main(*args, **kwargs) File "c:\python37\lib\site-packages\click\core.py", line 782, in main rv = self.invoke(ctx) File "c:\python37\lib\site-packages\click\core.py", line 1259, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "c:\python37\lib\site-packages\click\core.py", line 1066, in invoke return ctx.invoke(self.callback, **ctx.params) File "c:\python37\lib\site-packages\click\core.py", line 610, in invoke return callback(*args, **kwargs) File "c:\python37\lib\site-packages\mkdocs\__main__.py", line 152, in build_command build.build(config.load_config(**kwargs), dirty=not clean) File "c:\python37\lib\site-packages\mkdocs\commands\build.py", line 271, in build _populate_page(file.page, config, files, dirty) File "c:\python37\lib\site-packages\mkdocs\commands\build.py", line 168, in _populate_page 'page_markdown', page.markdown, page=page, config=config, files=files File "c:\python37\lib\site-packages\mkdocs\plugins.py", line 94, in run_event result = method(item, **kwargs) File "c:\python37\lib\site-packages\mkapi\plugins\mkdocs.py", line 116, in on_page_markdown markdown, abs_src_path, self.abs_api_paths, filters=self.config["filters"] File "<string>", line 8, in __init__ File "c:\python37\lib\site-packages\mkapi\core\page.py", line 41, in __post_init__ self.markdown = "\n\n".join(self.split(source)) File "c:\python37\lib\site-packages\mkapi\core\page.py", line 75, in split inherit(node) File "c:\python37\lib\site-packages\mkapi\core\inherit.py", line 155, in inherit for base in bases: File "c:\python37\lib\site-packages\mkapi\core\inherit.py", line 130, in <genexpr> yield node, (get_node(base) for base in bases) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 234, in get_node return Node(obj, sourcefile_index) File "<string>", line 5, in __init__ File "c:\python37\lib\site-packages\mkapi\core\node.py", line 31, in __post_init__ super().__post_init__() File "c:\python37\lib\site-packages\mkapi\core\structure.py", line 106, in __post_init__ self.members = self.get_members() File "c:\python37\lib\site-packages\mkapi\core\node.py", line 82, in get_members return get_members(self.obj) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 214, in get_members member = get_node(obj, sourcefile_index) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 234, in get_node return Node(obj, sourcefile_index) File "<string>", line 5, in __init__ File "c:\python37\lib\site-packages\mkapi\core\node.py", line 31, in __post_init__ super().__post_init__() File "c:\python37\lib\site-packages\mkapi\core\structure.py", line 104, in __post_init__ self.docstring = get_docstring(obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 294, in get_docstring postprocess(docstring, obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 236, in postprocess parse_bases(doc, obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 194, in parse_bases objs = obj.mro()[1:-1] TypeError: descriptor 'mro' of 'type' object needs an argument

Can fix that by replacing the line with:

try:
    objs = obj.mro()[1:-1]
except TypeError:
    objs = obj.mro(type)[1:-1]

but not sure if that is the best fix.

For me it happened for a class inherited from QtCharts.QAbstractSeries (https://pypi.org/project/PyQtChart/)

This here might be a similar issue, from another project:
https://github.com/agronholm/sphinx-autodoc-typehints/issues/73

[Enhancement] Theme support

It would be nice to have the option to use different themes in mkdocs.

My suggestion: read the theme entry from mkdocs.yml and choose the corresponding theme from mkapi/theme folder. If the theme is not available than use the default one.

Additionally i would like to have two options for the plugin:

  • theme_dir: (custom theme dir for adding custom themes)
  • theme: override the mkdocs value if theme should not match

Currently i am adding a custom css file to overwrite the theme to match the readthedocs-style, but this isn't ideal.

mkapi does not detect classmethods on abstract base class

mkapi does not seem to detect classmethods in my setup.

Simplified example:

from abc import ABCMeta, abstractmethod
import json

class Base(object, metaclass=ABCMeta):
    @abstractmethod
    def __init__(self, some_arg):
        """[summary]

        Args:
            some_arg ([type]): [description]

        Raises:
            NotImplementedError: [description]
        """
        raise NotImplementedError()

    @classmethod
    def from_json(cls, json_string):
        """[summary]

        Args:
            json_string ([type]): [description]

        Raises:
            NotImplementedError: [description]
        """
        raise NotImplementedError()

    def to_json(self):
        """[summary]
        """
        return json.dumps(self.data)


class Child(Base):
    def __init__(self, some_arg):
        """[summary]

        Args:
            some_arg ([type]): [description]
        """
        self.some_arg = some_arg
        self.data = None

    @classmethod
    def from_json(cls, json_string):
        """[summary]

        Args:
            json_string ([type]): [description]
        """
        child = cls()
        child.data = json.loads(json_string)
        return child        

This should render docs for both classes where they both have from_json and to_json. Instead the classmethod from_json is missing from both.

EDIT: when removing the metaclass=ABCMeta from the baseclass the classmethods pop up. Is this described behaviour?

mkapi fails for me after fresh install

Steps to pre-produce

  • mkdir test-mkapi
  • cd test-mkapi
  • python3.7 -m venv .env
  • source .env/bin/activate
  • pip install mkdocs
  • pip install mkapi
  • mkdocs new .

edit mkdocs.yml to look like

site_name: My Docs
plugins:
  - search
  - mkapi

Then issue mkdocs serve

Expected behavior:

Mkdocs will serve the default mkdocs website on 127.0.0.1:8000

Actual behavior

  <snip>
  File "/home/daniel/Repositories/binance-asyncio/.env/lib/python3.9/site-packages/mkapi/plugins/api.py", line 19, in create_nav
    for page in nav:
TypeError: 'NoneType' object is not iterable

Note

If i change mkdocs.yml to

site_name: My Docs
plugins:
  - search

all is good. generates, Mkdocs will serve the default mkdocs website on 127.0.0.1:8000 as expected

why raise configuration error?

my mkdocs.yml:

site_name: Omicron

nav: 
  - Home: index.md
  - History: history.md

theme: readthedocs

markdown_extensions:
  - admonition
plugins:
  - mkapi:
    src_dirs: [omicron]

have tried python -c import omicron without error.

The error raised (by command mkdocs serve -v -a 0.0.0.0:8000):

DEBUG   -  Config value: 'markdown_extensions' = ['toc', 'tables', 'fenced_code', 'admonition'] 
DEBUG   -  Config value: 'mdx_configs' = None 
DEBUG   -  Config value: 'strict' = False 
DEBUG   -  Config value: 'remote_branch' = 'gh-pages' 
DEBUG   -  Config value: 'remote_name' = 'origin' 
DEBUG   -  Config value: 'extra' = {} 
DEBUG   -  Config value: 'plugins' = [{'mkapi': None, 'src_dirs': ['omicron']}] 

Aborted with 1 Configuration Errors!
``

KeyError on __dataclass_field__

Hi,

I'm trying to use your mkdocs plugin for a project and I get the following error:

  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/node.py", line 101, in get_kind
    if hasattr(obj, "__dataclass_fields__") and hasattr(obj, "__qualname__"):
KeyError: '__dataclass_fields__'
Full console output of `mkdocs build`

(venv38) ~/Git/plato-common-egse/MKDOCS (develop)> mkdocs build
Traceback (most recent call last):
  File "/Users/rik/Git/plato-common-egse/venv38/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/commands/build.py", line 236, in build
    config = config['plugins'].run_event('config', config)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/mkdocs.py", line 47, in on_config
    config, self.abs_api_paths = mkapi.plugins.api.create_nav(config)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/api.py", line 23, in create_nav
    page[key], abs_api_paths_ = collect(value, docs_dir, config_dir)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/api.py", line 43, in collect
    module = get_module(package_path)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
    return Module(obj)
  File "<string>", line 6, in __init__
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
    super().__post_init__()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
    self.members = self.get_members()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
    return get_members(self.obj)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
    module = get_module(name)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
    return Module(obj)
  File "<string>", line 6, in __init__
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
    super().__post_init__()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
    self.members = self.get_members()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
    return get_members(self.obj)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
    module = get_module(name)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
    return Module(obj)
  File "<string>", line 6, in __init__
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
    super().__post_init__()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
    self.members = self.get_members()
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
    return get_members(self.obj)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
    module = get_module(name)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
    return Module(obj)
  File "<string>", line 6, in __init__
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 30, in __post_init__
    objects = get_objects(self.obj)
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 71, in get_objects
    if not get_kind(obj):
  File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/node.py", line 101, in get_kind
    if hasattr(obj, "__dataclass_fields__") and hasattr(obj, "__qualname__"):
KeyError: '__dataclass_fields__'

Error when inherting from np.ndarray

Given the following class:

import numpy as np

class Thing(np.ndarray):
    def something(self):
         return 42

Running mkapi on this results in:

self = Section('', num_items=0), section = Section('Parameters', num_items=7), force = True

    def merge(self, section: "Section", force: bool = False) -> "Section":
        """Returns a merged Section

        Examples:
            >>> s1 = Section('Parameters', items=[Item('a', 's'), Item('b', 'f')])
            >>> s2 = Section('Parameters', items=[Item('a', 'i'), Item('c', 'd')])
            >>> s3 = s1.merge(s2)
            >>> s3.items
            [Item('a', 's'), Item('b', 'f'), Item('c', 'd')]
            >>> s3 = s1.merge(s2, force=True)
            >>> s3.items
            [Item('a', 'i'), Item('b', 'f'), Item('c', 'd')]
            >>> s3 = s2.merge(s1)
            >>> s3.items
            [Item('a', 'i'), Item('c', 'd'), Item('b', 'f')]
        """
        if section.name != self.name:
>           raise ValueError(f"Different name: {self.name} != {section.name}.")
E           ValueError: Different name:  != Parameters.

mkapi/core/base.py:422: ValueError

Adding a small test case to test_core_inherit.py reproduces this:

    def test_numpy_thing():
        import numpy as np

        class Thing(np.ndarray):
            pass

       section = get_section(Node(Thing), "Parameters", "Docstring")

I tried to dig into this to see if it was a simple fix, but I can't seem to find anything. The parameters section seems to be an empty, default section with the name '' which I think is incorrect.

Annotations break methods docstrings

I have a file with the following code:

@pytest.fixture(scope="module")
def chart_path(pytestconfig) -> str:
    """Return a path to the chart under test (from command line argument)."""
    return pytestconfig.getoption("chart_path")

mkapi in page mode skips this. If I remove the annotation, the docstring is picked up correctly.

Instructions only generate API for "mkapi"?

(Edit: Found a bug, will make a PR)

I couldn't find instructions on how set the package (sorry if I'm missing something). I am only able to generate mkdocs itself.

Name: mkapi
Version: 1.0.12
Summary: An Auto API Documentation tool.
Home-page: https://mkapi.daizutabi.net
Author: daizutabi
Author-email: [email protected]
License: MIT
Location: /home/t/work/python/libvcs/.venv/lib/python3.7/site-packages
Requires: jinja2, markdown
Required-by:
libvcs on ๎‚  new-docs [โœ˜!] โฏ python -V
Python 3.7.7
libvcs on ๎‚  new-docs [โœ˜!] โฏ pip show mkdocs
Name: mkdocs
Version: 1.1.2
Summary: Project documentation with Markdown.
Home-page: https://www.mkdocs.org
Author: Tom Christie
Author-email: [email protected]
License: BSD
Location: /home/t/work/python/libvcs/.venv/lib/python3.7/site-packages
Requires: PyYAML, Jinja2, tornado, livereload, lunr, click, Markdown
Required-by: mkdocstrings, mkdocs-material

image

mkdocs.yml:

# mkdocs.yml
site_name: libvcs
site_url: https://libvcs.git-pull.com
repo_url: https://github.com/vcs-python/libvcs
repo_name: 'GitHub'
theme:
  name: "material"
  custom_dir: .
  logo: assets/images/libvcs.svg
  favicon: assets/images/favicon.ico

plugins:
  - search
  - mkapi

nav:
  - index.md
  - API: mkapi/api/mkapi
  #   - API: mkapi/api/libvcs will crash

Detect `mkapi/` in nested `nav`

I was trying to do:

nav:
  - "About": index.md
  - "Install": install.md
  - "Getting Started": started.md
  - "Config": config.md
  - "FAQ": faq.md
  - "Development":
    - "Contributing": contributing/index.md
    - "Architecture": contributing/architecture.md
    - "API": mkapi/api/lib-python/foo

but create_nav is not recursive, only finding docs in top level entries

def create_nav(config, global_filters):
    nav = config["nav"]
    docs_dir = config["docs_dir"]
    config_dir = os.path.dirname(config["config_file_path"])
    abs_api_paths = []
    for page in nav:
        if isinstance(page, dict):
            for key, value in page.items():
                if isinstance(value, str) and value.startswith("mkapi/"):
                    page[key], abs_api_paths_ = collect(
                        value, docs_dir, config_dir, global_filters
                    )
                    abs_api_paths.extend(abs_api_paths_)
    return config, abs_api_paths

Requiring me to do

nav:
  - "About": index.md
  - "Install": install.md
  - "Getting Started": started.md
  - "Config": config.md
  - "FAQ": faq.md
  - "Development":
    - "Contributing": contributing/index.md
    - "Architecture": contributing/architecture.md
  - "API": mkapi/api/lib-python/foo

Mock unavailable libraries?

Hi ,

I would like do to document a project that makes heavy use of external libraries where I don't have access to the sources. Does mkapi offer something similar to mocks in sphinxs/autodoc
autodoc_mock_imports = ["django","td"]?

Thanks in advance

Consider a conda package

It would help teams using conda to use this library if there were a conda package on conda-forge. You can pip-install into a conda environment, but that is problematic because you will get dependencies from unpredictable locations, depending on what is already installed in the environment. I have not myself tried these instructions, so I don't know how much work this is.

Thanks

Andy

Enum classes display not very useful

Currently, linking an enum.Enum subclass returns the definition of the main Enum class, which is not very useful. It would be more useful if it would display the individual elements (or even just the source code).

For example, this class definition:

from enum import Enum

class EnumExample(Enum):
    FOO = 'foo'
    BAR = 'bar'

... linked like this:

# Enum Test

![mkapi](diffusion.datatypes.EnumExample)

... looks like this:

Screenshot_2020-08-14_11-36-21

importing within the same package

Say I have the following directory structure

- package_name
  - module1.py
  - module2.py
- docs/
  - index.md
mkdocs.yml

and i have

... snip ...
plugins:
  - search
  - mkapi:
      src_dirs: [package]

in my mkdocs.yml. And say we have two classes, ClassFirst in module1.py and ClassSecond in module2.py, if I now add docstrings to ClassFirst and do mkdocs build, everything works and my documentation is generated.

Actual problem
If i now where to import ClassSecond into module1.py , everything breaks. It doesn't matter if I use

from package_name.module2 import ClassSecond  

or

from .module2 import ClassSecond  

I import different from other modules within the same package all the time, doesn't mkapi support this?

Support for `LIteral`

First of, thanks for this library. Of all the mkdocs API documentation libraries this one has worked the best so far. God knows we need something besides sphinx for making library documentation!

I ran into an issue with a function that uses a Literal type. EG

from typing import Literal  # or from typing_extensions import Literal

def some_func(method: Literal['one', 'two']) -> str:
    ...

will raise something like:

line 305, in to_string_args
    name = annotation.__origin__.__name__.lower()
AttributeError: '_LiteralSpecialForm' object has no attribute '__name__'

I don't think it will be a hard fix and I am happy to submit a PR if it is just a simple issue of getting a str rep for Literal.

Override package/module discovery in page mode to load file even if no docstring is present

In the docs, it says:

image

For Python files that contain only a single class however, adding a docstring feels kind of unnecessary and redundant. Is it possible to override this functionality and force loading files even if they have no docstring? My current workaround is to add a docstring with invisible character, which kinda works but creates too much blank space in the docs:

image

Use try-except instead of hasattr for detection of __wrapped__ and __pytest_wrapped__

mkapi/mkapi/core/object.py

Lines 201 to 203 in 6e0cf8f

if hasattr(obj, "__wrapped__"):
return get_origin(obj.__wrapped__)
if hasattr(obj, "__pytest_wrapped__"):

When some classes have improper or complicated __getattr__ implemented, this will raise some errors unexpectedly.
We should use try-except instead:

try:
     obj.__wrapped__
    # Do something with obj.__wrapped__
    # or in else
except AttributeError:
    # no __wrapped__ attribute

Add configuration for deep subclasses

If a class has many ancestors, I don't all of them to be inherited. Is it possible to add configurations to limit this? or to disable inheritance?

[Enhancement] hide __init__() method if no docstring

Another possible enhancement could be to hide the init() method when displaying a class if the docstring is empty, since all parameters appear in the class header and the docstring of the class supposedly document those.

Currently a section with the init method is created with the following content :
Initialize self. See help(type(self)) for accurate signature.
even if there is no docstring

Support python 3.5+

Hi @daizutabi ,

Is there any reason this package is does not support python 3.5 and 3.6? MkDocs officially still supports 3.5+ (link). My companies hadoop cluster is still running python 3.6, and I'd like to use your package there.

Any chance you'd be willing to increase support for older python versions?

[Enhancement] Add Node header into the table of content?

Hi,

First, thanks for allowing me to make beautiful API docs so easily!!

This is more a feature suggestion and I am not sure of the internal, so I don't know if it is possible.
But could we have the option to add the main nodes to the toc?
So If I use ![mkapi](package.module.Class), then that would also add the Class methods in the toc ?

That would be terrific

[Enhancement] Document only a specifc method from a class

Another use case that I could see myself using is if we only want to display the bloc regarding a specific method from a class. So for example using: ![mkapi](numpy_style.ExampleClass.message)

It seems at the moment it is not possible, or at least it created an error on my machine.
And not sure if there is another way to achieve this, but that would be interesting to have the possibility to do so.

Thanks!

Exception thrown with non-native type annotations

With the annotation "Union[subprocess.Popen[str], subprocess.Popen[bytes]]", I'm getting

  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 82, in get_members
    return get_members(self.obj)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 209, in get_members
    member = get_node(obj, sourcefile_index)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 229, in get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 31, in __post_init__
    super().__post_init__()
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/structure.py", line 100, in __post_init__
    signature = get_signature(obj)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 357, in get_signature
    return Signature(obj)
  File "<string>", line 7, in __init__
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 75, in __post_init__
    self.returns = resolve_forward_ref(self.obj, return_annotation)
  File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 348, in resolve_forward_ref
    type = eval(name, globals)
  File "<string>", line 1, in <module>
TypeError: 'type' object is not subscriptable

subprocess.Popen does not native support type subscription (which is why I have to have the "" around it) but mypy supports it, and with at least my config settings, requires it.

Official answer - Is this project still maintained?

Hi @daizutabi, would appreciate if you could declare the official position of this project. Seems like it's no longer being actively developed or maintain. This is a shame but fair enough. Can you confirm pls?

fwiw our main blocker is it seems to not work with newer versions of Python (3.11 in our case but seem to be broken from Python v3.9 onwards based on other users comments). #56

Thanks

How to keep methods details sorted?

I'm trying out mkapi and generated some docs for a class. The methods in the overview (green) are all nicely ordered alphabetically, but the method details (red) seem ordered randomly. Is there a way to keep the same order as the overview section?

Screenshot 2022-11-21 at 16 41 56

Multiple assignments per line: list index out of range

I get a n error with the latest commit (6fe41e2).
Does not occur in the previous commit.

It think the problem is if the code has multiple assignments per line:

class Test():
    """ bla bla blubb
    
    Attributes: 
        _foo: a foobar value
    """

    def __init__(self):
        """ initizizes test object """
        self._foo: str = "BAR"
        self._bar: int = 0

    def class_method(self, bar: str = "BAR") -> float:
        """ class method

        Args:
            bar: blubb
        """
        self._foo = bar
        self._foo, self._bar = bar, 0 # booom crash!
        return 0.0

Trace:

Traceback (most recent call last):
  File "./mkapi/.env/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 271, in build
    _populate_page(file.page, config, files, dirty)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 167, in _populate_page
    page.markdown = config['plugins'].run_event(
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "./mkapi/mkapi/plugins/mkdocs.py", line 108, in on_page_markdown
    page = Page(markdown, abs_src_path, self.abs_api_paths)
  File "<string>", line 6, in __init__
  File "./mkapi/mkapi/core/page.py", line 37, in __post_init__
    self.markdown = "\n\n".join(self.split(source))
  File "./mkapi/mkapi/core/page.py", line 64, in split
    node = get_node(name)
  File "./mkapi/mkapi/core/node.py", line 209, in get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
    super().__post_init__()
  File "./mkapi/mkapi/core/structure.py", line 104, in __post_init__
    self.members = self.get_members()
  File "./mkapi/mkapi/core/node.py", line 59, in get_members
    return get_members(self.obj)
  File "./mkapi/mkapi/core/node.py", line 189, in get_members
    member = get_node(obj, sourcefile_index)
  File "./mkapi/mkapi/core/node.py", line 209, in get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
    super().__post_init__()
  File "./mkapi/mkapi/core/structure.py", line 99, in __post_init__
    signature = get_signature(obj)
  File "./mkapi/mkapi/core/signature.py", line 330, in get_signature
    return Signature(obj)
  File "<string>", line 7, in __init__
  File "./mkapi/mkapi/core/signature.py", line 71, in __post_init__
    self.set_attributes()
  File "./mkapi/mkapi/core/signature.py", line 109, in set_attributes
    for name, (type, description) in get_attributes(self.obj).items():
  File "./mkapi/mkapi/core/attribute.py", line 219, in get_attributes
    return get_class_attributes(obj)
  File "./mkapi/mkapi/core/attribute.py", line 165, in get_class_attributes
    return get_attributes_dict(attr_lineno, source, prefix="self.")
  File "./mkapi/mkapi/core/attribute.py", line 146, in get_attributes_dict
    description = get_description(lines[:stop], lineno)
  File "./mkapi/mkapi/core/attribute.py", line 67, in get_description
    line = lines[index]
IndexError: list index out of range

Error when numpy array is default value

Error when numpy array is default value, e.g.:

    def add_load(
        self,
        shape_type: str,
        shape_group_name: str,
        load_case_number: int = 0,
        translations: np.ndarray = np.zeros(3),
        rotations: np.ndarray = np.zeros(3),
    ):

Error message:

....
  File "....\python38\lib\site-packages\mkapi\core\signature.py", line 62, in __post_init__
    if default == inspect.Parameter.empty:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

using colon in docstring - interpreted as return type

Using colons in method/function docstring leads to a problem where mkapi interprets this line as return type of a function:

def show_me_the_problem(self):
"""i show you that this: is a problem"""
    pass

Screenshot:
Screenshot from 2020-06-19 07-06-24

Python 3.9 : Accessing __args__ raises attribute error

__args__ was removed in https://bugs.python.org/issue40397 and https://bugs.python.org/issue40398 . It seems a lot of places use it that causes test failures in Python 3.9. A quick grep of args shows many places and can cause failures like this. python 3.8 added typing.get_args as a helper.

rg __args__
mkapi/core/signature.py
164:        if hasattr(annotation, "__args__") and annotation.__args__:
165:            if len(annotation.__args__) == 1:
166:                return to_string(annotation.__args__[0], obj=obj)
187:        args = [to_string(x, obj=obj) for x in annotation.__args__]
193:        if type(annotation.__args__[0]) == TypeVar:
195:        args = [to_string(x, obj=obj) for x in annotation.__args__]
200:    if not hasattr(annotation, "__args__"):
202:    if len(annotation.__args__) == 0:
204:    if len(annotation.__args__) == 1:
231:    if type(annotation.__args__[0]) == TypeVar:
233:    type_ = f"{name} of " + to_string(annotation.__args__[0], obj=obj)
256:    args = annotation.__args__
304:    args = annotation.__args__

Sample failure after trying to fix #36

==================================== FAILURES =====================================
______________________________ test_class_attribute _______________________________

    def test_class_attribute():
        attrs = get_attributes(A)
        assert attrs
        for k, (name, (type, markdown)) in enumerate(attrs.items()):
            assert name == ["x", "y", "a", "z"][k]
            assert markdown.startswith(["Doc ", "list of", "", "Docstring *after*"][k])
            assert markdown.endswith(["attribute.", "specified.", "", "supported."][k])
            if k == 0:
                assert type is int
            elif k == 1:
                assert type is None
            elif k == 2:
                assert not markdown
            elif k == 3:
>               x = signature.to_string(type)

tests/core/test_core_attribute.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mkapi/core/signature.py:187: in to_string
    args = [to_string(x, obj=obj) for x in annotation.__args__]
mkapi/core/signature.py:187: in <listcomp>
    args = [to_string(x, obj=obj) for x in annotation.__args__]
mkapi/core/signature.py:187: in to_string
    args = [to_string(x, obj=obj) for x in annotation.__args__]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = typing.Tuple, attr = '__args__'

    def __getattr__(self, attr):
        # We are careful for copy and pickle.
        # Also for simplicity we just don't relay all dunder names
        if '__origin__' in self.__dict__ and not _is_dunder(attr):
            return getattr(self.__origin__, attr)
>       raise AttributeError(attr)
E       AttributeError: __args__

/usr/lib/python3.9/typing.py:648: AttributeError

mkapi seems to misinterpret the `See Also` section of numpy docs

Hey there,
I'm trying to set up mkapi to add the API of a package to its documentation. All is well, except for a module that contains a function with a See Also section in its numpy docstring.
Somehow mkapi seems to fail its interpretation, rendering (part of) it as a new H2 header:
Schermata da 2022-07-11 17-16-40

For reference:

  • The mkdocs configuration is here and the API page file itself is here. I'm using the readthedocs default mkdocs theme.
  • The function that misbehaves is here, together with the two functions after that show again a See Also H2 within a Notes section: here and here
  • I'm on python 3.7, Ubuntu 18.04, mkapi 1.0.14, mkdocs 1.2.4, and Markdown 3.2.1 - it otherwise has conflicting dependencies with flake8.
This is the dependency tree of mkapi

$ pipdeptree -p mkapi
mkapi==1.0.14
  - jinja2 [required: Any, installed: 3.0.3]
    - MarkupSafe [required: >=2.0, installed: 2.1.1]
  - markdown [required: Any, installed: 3.2.1]
    - setuptools [required: >=36, installed: 61.3.0]

This is the dependency tree of mkdocs

$ pipdeptree -p mkdocs
mkdocs==1.2.4
  - click [required: >=3.3, installed: 8.0.4]
    - importlib-metadata [required: Any, installed: 4.2.0]
      - typing-extensions [required: >=3.6.4, installed: 4.0.1]
      - zipp [required: >=0.5, installed: 3.2.0]
  - ghp-import [required: >=1.0, installed: 2.1.0]
    - python-dateutil [required: >=2.8.1, installed: 2.8.2]
      - six [required: >=1.5, installed: 1.13.0]
  - importlib-metadata [required: >=3.10, installed: 4.2.0]
    - typing-extensions [required: >=3.6.4, installed: 4.0.1]
    - zipp [required: >=0.5, installed: 3.2.0]
  - Jinja2 [required: >=2.10.1, installed: 3.0.3]
    - MarkupSafe [required: >=2.0, installed: 2.1.1]
  - Markdown [required: >=3.2.1, installed: 3.2.1]
    - setuptools [required: >=36, installed: 61.3.0]
  - mergedeep [required: >=1.3.4, installed: 1.3.4]
  - packaging [required: >=20.5, installed: 21.3]
    - pyparsing [required: >=2.0.2,!=3.0.5, installed: 2.4.5]
  - PyYAML [required: >=3.10, installed: 5.3.1]
  - pyyaml-env-tag [required: >=0.1, installed: 0.1]
    - pyyaml [required: Any, installed: 5.3.1]
  - watchdog [required: >=2.0, installed: 2.1.9]

I'm failing to use the Page Mode for other issues, but I also want to have more control on what is displayed and how.

[Enhancement] magic/dunder methods

Currently magic/dunder methods are not handled by mkapi:

e.g.:

  • __add__
  • __mul__
  • __eq__
  • __repr__
  • __str__
  • __len__
  • ...

Would be nice to have them in the API docs if they are documented.

[Enhancement] Display inheritance in the generated doc of class

Another interesting improvement could be to be able to display the parent class if the class is a subclass. i.e, just listing the parent classes after the list of parameters.

For example, the following class:

class SubClass(MixinExt, Mixin2):
    def __init__(self, string_a: str):
        pass

Would result in a documentation like so:
mkapi-inheritance

Not sure what you think about that, but I would find it very useful for my usecase.

Thanks and regards

ValueError: Could not find object: <module> in GH actions/readthedocs

I can successfully run it locally. However, when I try to deploy it via GH actions or rtd, both gave the same error:

Traceback
Traceback (most recent call last):
  File "/home/docs/.pyenv/versions/3.7.3/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/docs/.pyenv/versions/3.7.3/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/__main__.py", line 192, in 
    cli()
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/__main__.py", line 152, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/commands/build.py", line 236, in build
    config = config['plugins'].run_event('config', config)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/mkdocs.py", line 51, in on_config
    config, self.config["filters"]
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/api.py", line 24, in create_nav
    value, docs_dir, config_dir, global_filters
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/api.py", line 47, in collect
    module = get_module(package_path)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/core/module.py", line 96, in get_module
    obj = get_object(name)
  File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/core/object.py", line 39, in get_object
    raise ValueError(f"Could not find object: {name}")
ValueError: Could not find object: varname

And you can see the configurations here:

https://github.com/pwwang/python-varname/tree/857b4c0206e4315d00a3ab85ceb932e9aebf1f69

python 3.9 - AttributeError: 'Name' object has no attribute 'value'

Command : mkdocs build -f docs/mkdocs.yml -v

When i run the command with python 3.8, it works.
When i run the command with python 3.9, it fails :

DEBUG   -  Config value: 'plugins' = PluginCollection([('search', <mkdocs.contrib.search.SearchPlugin object at 0x7f9f49027970>), ('mkapi', <mkapi.plugins.mkdocs.MkapiPlugin object at 0x7f9f48fbd880>)]) 
Traceback (most recent call last):
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/__main__.py", line 152, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/commands/build.py", line 236, in build
    config = config['plugins'].run_event('config', config)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/mkdocs.py", line 50, in on_config
    config, self.abs_api_paths = mkapi.plugins.api.create_nav(
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/api.py", line 23, in create_nav
    page[key], abs_api_paths_ = collect(
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/api.py", line 47, in collect
    module = get_module(package_path)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 104, in get_module
    module = Module(obj)
  File "<string>", line 4, in __init__
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 27, in __post_init__
    super().__post_init__()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 106, in __post_init__
    self.members = self.get_members()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 48, in get_members
    return get_members(self.obj)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 81, in get_members
    module = get_module(name)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 104, in get_module
    module = Module(obj)
  File "<string>", line 4, in __init__
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 28, in __post_init__
    self.node = get_node(self.obj)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 229, in get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 31, in __post_init__
    super().__post_init__()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 106, in __post_init__
    self.members = self.get_members()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 82, in get_members
    return get_members(self.obj)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 209, in get_members
    member = get_node(obj, sourcefile_index)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 229, in get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 31, in __post_init__
    super().__post_init__()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 100, in __post_init__
    signature = get_signature(obj)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 356, in get_signature
    return Signature(obj)
  File "<string>", line 7, in __init__
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 71, in __post_init__
    self.set_attributes()
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 118, in set_attributes
    for name, (type, description) in get_attributes(self.obj).items():
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 269, in get_attributes
    return get_class_attributes(obj)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 185, in get_class_attributes
    attr_lineno = get_attributes_with_lineno(nodes, module)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 121, in get_attributes_with_lineno
    attr, lineno, type_str = parse_annotation_assign(x)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 61, in parse_annotation_assign
    type = parse_node(assign.annotation)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 47, in parse_node
    return parse_subscript(x)
  File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 23, in parse_subscript
    slice = parse_node(x.slice.value)
AttributeError: 'Name' object has no attribute 'value'

Have you any idea ?

Python 3.10

What are the plans to support Python version 3.10?

Automatic API generation fails to handle namespace package

We use namespace packages so we don't clutter the global package namespace. This line in a mkdocs.yml trying to document namespacefoo.packagefoo does not produce the expected results:

nav:
  - API: mkapi/api/src/namespacefoo

I expect it to find and document namespacefoo.packagefoo. Instead it finds other packages in the same namespace installed in the current environment (e.g. namespacefoo.anotherpackage), but not namespacefoo.packagefoo.

I can convince mkapi to find namespacefoo.packagefoo with this mkdocs.yml:

nav:
  - API: mkapi/api/src/namespacefoo/packagefoo

But in this case:

  1. Internal cross references inside the python docstrings in namespacefoo/packagefoo/init.py don't seem to work at all.
  2. Internal cross-references inside the python docstrings in modules inside must namespacefoo/packagefoo with packagefoo.modulebar., for example:
    [Baz](packagefoo.modulebar.Baz)

I'd like to be able to use references that are obvious to someone reading the docstring without the web page. I think fully a qualified reference would be clear, if long: [Baz](namespacefoo.packagefoo.modulebar.Baz). It would be nice if you could also use Baz from a doctring inside the module containing Baz.

Links: Option to add trailing slash? Use trailing slash by default?

This is anecdotal, but CloudFront wants paths to end in a slash:

https://libvcs.git-pull.com/api/source/libvcs.hg/#libvcs.hg.MercurialRepo

https://libvcs.git-pull.com/api/source/libvcs.hg#libvcs.hg.MercurialRepo

image

Thoughts on adding this as a default behavior? Setting?

diff --git a/mkapi/core/postprocess.py b/mkapi/core/postprocess.py
index 959aa77..bab3313 100644
--- a/mkapi/core/postprocess.py
+++ b/mkapi/core/postprocess.py
@@ -11,7 +11,7 @@ def sourcelink(object: Object) -> str:
         link = f'<span id="{object.id}"></span>'
     else:
         link = ""
-    link += f'<a class="mkapi-src-link" href="../source/{object.module}'
+    link += f'<a class="mkapi-src-link" href="../source/{object.module}/'
     link += f'#{object.id}" title="Source for {object.id}">&lt;/&gt;</a>'
     return link
 
diff --git a/mkapi/templates/object.jinja2 b/mkapi/templates/object.jinja2
index da1ef7f..f7a0a11 100644
--- a/mkapi/templates/object.jinja2
+++ b/mkapi/templates/object.jinja2
@@ -11,7 +11,7 @@
   </div>
   {% if 'sourcelink' in filters or 'link' in filters or 'apilink' in filters -%}
   <div class="mkapi-src-link">
-    <a class="mkapi-src-link" href="../source/{{ object.module }}#{{ object.id }}" title="Source for {{ object.id }}">&lt;/&gt;</a>
+    <a class="mkapi-src-link" href="../source/{{ object.module }}/#{{ object.id }}" title="Source for {{ object.id }}">&lt;/&gt;</a>
   </div>
   {%- endif %}
 </div>

Currently I hard-code this in a forked package since I feel its too specialized (and I'm not sure what other static file hosts use)

Breadcrumbs in Readthedocs theme

In the readthedocs theme the breadcrumbs for mkapi in pagemode are not correctly displayed.
The line before API should not be displayed. I think that is a problem with the page.anchestors for the mkapi pages.

image

Steps to reproduce:

IPython dependency problem

Hello,

first of all i like your project. Its currently the best option for creating api-docs with mkdocs using google-style, nice work ๐Ÿ˜‰

Current Release 0.6.1 depends on Ipython package which is not listed in the dependencies.
after i updated the library and build with mkdocs i get the following error:

$mkdocs build -c -v
...
.env/lib/python3.8/site-packages/mkapi/utils.py", line 1, in <module>
    from IPython.display import HTML
ModuleNotFoundError: No module named 'IPython'

AbstractBaseClass - TypeError: descriptor 'mro' of 'type' object

Hello,

Current version (0.7.7) throws TypeError if the base class is Abstract (abc.ABC)

Rerproduce Error:
change the follwing in examples/inherit.py

from dataclasses import dataclass

from mkapi.core.base import Type
import abc

@dataclass
class Base(abc.ABC):
...

Trace:

ERROR   -  Error reading page 'usage/inherit.md': descriptor 'mro' of 'type' object needs an argument 
Traceback (most recent call last):
  File "./mkapi/.env/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 271, in build
    _populate_page(file.page, config, files, dirty)
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 167, in _populate_page
    page.markdown = config['plugins'].run_event(
  File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
    result = method(item, **kwargs)
  File "./mkapi/mkapi/plugins/mkdocs.py", line 86, in on_page_markdown
    page = Page(markdown, abs_src_path, self.abs_api_paths)
  File "<string>", line 6, in __init__
  File "./mkapi/mkapi/core/page.py", line 36, in __post_init__
    self.markdown = "\n\n".join(self.split(source))
  File "./mkapi/mkapi/core/page.py", line 57, in split
    node = get_node(name)
  File "./mkapi/mkapi/core/node.py", line 197, in get_node
    return _get_node(obj, sourcefile_index)
  File "./mkapi/mkapi/core/node.py", line 180, in _get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
    super().__post_init__()
  File "./mkapi/mkapi/core/tree.py", line 49, in __post_init__
    self.members = self.get_members()
  File "./mkapi/mkapi/core/node.py", line 58, in get_members
    return get_members(self.obj)
  File "./mkapi/mkapi/core/node.py", line 169, in get_members
    member = get_node(obj, sourcefile_index)
  File "./mkapi/mkapi/core/node.py", line 197, in get_node
    return _get_node(obj, sourcefile_index)
  File "./mkapi/mkapi/core/node.py", line 180, in _get_node
    return Node(obj, sourcefile_index)
  File "<string>", line 5, in __init__
  File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
    super().__post_init__()
  File "./mkapi/mkapi/core/tree.py", line 48, in __post_init__
    self.docstring = get_docstring(obj)
  File "./mkapi/mkapi/core/docstring.py", line 297, in get_docstring
    postprocess(docstring, obj)
  File "./mkapi/mkapi/core/docstring.py", line 230, in postprocess
    add_bases(doc, obj)
  File "./mkapi/mkapi/core/docstring.py", line 214, in add_bases
    bases = obj.mro()[1:-1]
TypeError: descriptor 'mro' of 'type' object needs an argument

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.