Giter Club home page Giter Club logo

stubdoc's Introduction

stubdoc

stubdoc is a Python library that append docstring to stub files.

What problem will be solved by this library?

mypy's stubgen command that create stub files does not append docstring. So if stub file exists and IDE prioritize stub's completion then docstring will not appear on IDE.

So that this library add docstring to stub files to display that.

For more mypy's stubgen command details, please see mypy documentation, Automatic stub generation (stubgen).

For example, suppose that the following code's module exists (sample/sample.py):

from random import randint

sample_int: int = 100


def sample_func(a: int, b: str) -> bool:
    """
    Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    Parameters
    ----------
    a : int
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    b : str
        ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    Returns
    -------
    c : bool
        Ut enim ad minim veniam, quis nostrud exercitation.
    """
    return True


class SampleClass:

    def __init__(self) -> None:
        """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        """

    @property
    def sample_property(self) -> int:
        """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.

        Returns
        -------
        d : int
            ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        """
        return randint(0, 100)

mypy's stubgen command will generate stub files as follows (stubgen command will not add docstring):

sample_int: int

def sample_func(a: int, b: str) -> bool: ...

class SampleClass:
    def __init__(self) -> None: ...
    @property
    def sample_property(self) -> int: ...

And then, this library's command will add the docstring to stub doc as follows, so IDE's code completion will show docstring:

sample_int: int

def sample_func(a: int, b: str) -> bool:
    """
    Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    Parameters
    ----------
    a : int
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    b : str
        ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

    Returns
    -------
    c : bool
        Ut enim ad minim veniam, quis nostrud exercitation.
    """

class SampleClass:
    def __init__(self) -> None:
        """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        """
    @property
    def sample_property(self) -> int:
        """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.

        Returns
        -------
        d : int
            ed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        """

Installing

Installation via pip command is provided:

$ pip install stubdoc

Dependencies

  • Supported Python 3.8 or later (tested on 3.8.5). Probably works on Python 3.6.x or later (but not tested).

Usage

Notes: specified module need to be able to import. Stubdoc will replace paths to package path (e.g., 'sample/path.py' to 'sample.path'), so that paths argument can not be specified upper level directory or root directory (e.g., '/sample/path.py' or '../sample/path').

This command will add docstring to stub file. Currently supported one-line stub implementation, like mypy's stubgen
command, something as follows: def any_func(a: int, b: str) -> None: ... If line break exists after colon, this
command will not work correctly. Also not supported nested function, etc.

optional arguments:
  -h, --help            show this help message and exit
  -m MODULE_PATH, --module_path MODULE_PATH
                        Stub file's original module path. e.g., sample/path.py
  -s STUB_PATH, --stub_path STUB_PATH
                        Target stub file path. e.g., sample/path.pyi

Command example:

$ stubdoc -m samples/sample.py -s out/samples/sample.pyi

or

$ stubdoc --module_path samples/sample.py --stub_path out/samples/sample.pyi

Or maybe Python interface is useful, like Django environment:

from stubdoc import add_docstring_to_stubfile

add_docstring_to_stubfile(
    original_module_path='sample/path.py',
    stub_file_path='sample/path.pyi')

Limitations

This library supported only one-line stub implementation, like this:

def sample_func(a: int, b: str) -> bool: ...

class SampleClass:
    def __init__(self) -> None: ...
    @property
    def sample_property(self) -> int: ...

Not supported line breaks after function's colon:

def sample_func(a: int, b: str) -> bool:
    ...

class SampleClass:
    def __init__(self) -> None:
        ...
    @property
    def sample_property(self) -> int:
        pass

Also not supported nested functions, like this (docstring will add to only top-level function):

def sample_func_1(a: int, b: str) -> bool:
    def sample_func_2(c: list) -> None: ...

stubdoc's People

Contributors

cschulzetlk avatar currenttv avatar simon-ritchie avatar tobiasah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

stubdoc's Issues

Docstring missing for imported classes

Given the following module files:

# packages/package/parent.py

class Parent:
    def shared(self):
        """This should be shared by Child, too."""
# packages/package/child.py

class Child(Parent):
    pass

And the following stub files:

# stubs/package/child.pyi

class Child(Parent):
    def shared(self):
        ...

The following command does not copy over the docstring:

stubdoc --module_path=packages/package/child.py --stub_path=stubs/package/child.pyi

Add support for class-level docstring

Hi! Awesome library.

Currently, stubdoc only supports adding docstring to functions and class methods.

if '.' not in callable_name:
stub_str = _add_doctring_to_target_function(
stub_str=stub_str,
function_name=callable_name,
module=module,
)
continue
stub_str = _add_docstring_to_class_method(
stub_str=stub_str,
method_name=callable_name,
module=module,
)

It would be great if it supported class-level docstrings as well as class getters and setters (@property).

Stub file with docstring generated by stubdoc:

class NamedNode:
    @property
    def value(self) -> str: ...
    def __init__(self, value: str) -> None:
        """
        Initialize self.  See help(type(self)) for accurate signature.
        """
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: Any) -> bool: ...
    def __ge__(self, other: Any) -> bool: ...
    def __gt__(self, other: Any) -> bool: ...
    def __le__(self, other: Any) -> bool: ...
    def __lt__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...

Desired output:

class NamedNode:
    """An RDF `node identified by an IRI <https://www.w3.org/TR/rdf11-concepts/#dfn-iri>`_.

    :param value: the IRI as a string.
    :raises ValueError: if the IRI is not valid according to `RFC 3987 <https://tools.ietf.org/rfc/rfc3987>`_.

    The :py:func:`str` function provides a serialization compatible with N-Triples, Turtle, and SPARQL:

    >>> str(NamedNode('http://example.com'))
    '<http://example.com>'
    """
    @property
    def value(self) -> str:
        """the named node IRI.
        
        >>> NamedNode("http://example.com").value
        'http://example.com'
        """
    def __init__(self, value: str) -> None:
        """
        Initialize self.  See help(type(self)) for accurate signature.
        """
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: Any) -> bool: ...
    def __ge__(self, other: Any) -> bool: ...
    def __gt__(self, other: Any) -> bool: ...
    def __le__(self, other: Any) -> bool: ...
    def __lt__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...

Module import error

\pypoetry\cache\virtualenvs\stubdoc-kaloics5-py3.8\lib\site-packages\stubdoc\stubdoc.py", line 409, in _read_module
    module: ModuleType = importlib.import_module(name)
...\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 '...'

Limitation: does not support native modules

I was hoping to make docs for lcm's python bindings.

stubgen  -p lcm
stubdoc -m lcm/__init__.py -s out/lcm/__init__.pyi
stubdoc -m lcm/_lcm.so -s out/lcm/_lcm.pyi

The docs are successfully scraped from the python source init file and added to its stub, but the stub for the native module remains unchanged. Pydoc does display help for this native module.

Probably a fair bit more complicated to support, but making this issue at least for documentation.

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.