GithubHelp home page GithubHelp logo

jshwi / docsig Goto Github PK

View Code? Open in Web Editor NEW
34.0 2.0 2.0 2.25 MB

Check signature params for proper documentation

Home Page: https://docsig.readthedocs.io

License: MIT License

Python 98.90% Makefile 1.10%
compare docstring parameters signature tool function check ci document test

docsig's Introduction


docsig logo


License PyPI CI CodeQL pre-commit.ci status codecov.io readthedocs.org python3.8 Black isort docformatter pylint Security Status Known Vulnerabilities docsig

Check signature params for proper documentation

Supports reStructuredText (Sphinx), NumPy, and Google

Contributing

If you are interested in contributing to docsig please read about contributing here

Installation

$ pip install docsig

Usage

Commandline

usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a] [-k] [-T]
              [-I] [-n] [-v] [-s STR] [-d LIST] [-t LIST] [-e PATTERN] [-E PATH [PATH ...]]
              [path [path ...]]

Check signature params for proper documentation

positional arguments:
  path                                  directories or files to check

optional arguments:
  -h, --help                            show this help message and exit
  -V, --version                         show program's version number and exit
  -l, --list-checks                     display a list of all checks and their messages
  -c, --check-class                     check class docstrings
  -C, --check-class-constructor         check __init__ methods. Note: mutually incompatible
                                        with -c
  -D, --check-dunders                   check dunder methods
  -m, --check-protected-class-methods   check public methods belonging to protected classes
  -N, --check-nested                    check nested functions and classes
  -o, --check-overridden                check overridden methods
  -p, --check-protected                 check protected functions and classes
  -P, --check-property-returns          check property return values
  -i, --ignore-no-params                ignore docstrings where parameters are not
                                        documented
  -a, --ignore-args                     ignore args prefixed with an asterisk
  -k, --ignore-kwargs                   ignore kwargs prefixed with two asterisks
  -T, --ignore-typechecker              ignore checking return values
  -I, --include-ignored                 check files even if they match a gitignore pattern
  -n, --no-ansi                         disable ansi output
  -v, --verbose                         increase output verbosity
  -s STR, --string STR                  string to parse instead of files
  -d LIST, --disable LIST               comma separated list of rules to disable
  -t LIST, --target LIST                comma separated list of rules to target
  -e PATTERN, --exclude PATTERN         regular expression of files or dirs to exclude from
                                        checks
  -E PATH [PATH ...], --excludes PATH [PATH ...]
                                        path glob patterns to exclude from checks

Options can also be configured with the pyproject.toml file

[tool.docsig]
check-dunders = false
check-overridden = false
check-protected = false
disable = [
    "SIG101",
    "SIG102",
    "SIG402",
]
target = [
    "SIG202",
    "SIG203",
    "SIG201",
]

Flake8

docsig can also be used as a flake8 plugin. Install flake8 and ensure your installation has registered docsig

$ flake8 --version
7.1.0 (docsig: 0.60.1, mccabe: 0.7.0, pycodestyle: 2.12.0, pyflakes: 3.2.0) CPython 3.8.13 on Darwin

And now use flake8 to lint your files

$ flake8 example.py
example.py:1:1: SIG202 includes parameters that do not exist (params-do-not-exist) 'function'

With flake8 the pyproject.toml config will still be the base config, though the ini files flake8 gets it config from will override the pyproject.toml config. For flake8 all args and config options are prefixed with sig to avoid any potential conflicts with other plugins

[flake8]
sig-check-dunders = True
sig-check-overridden = True
sig-check-protected = True

API

>>> from docsig import docsig
>>> string = """
... def function(param1, param2, param3) -> None:
...     '''
...
...     :param param1: About param1.
...     :param param2: About param2.
...     :param param3: About param3.
...     '''
...     """
>>> docsig(string=string, no_ansi=True)
0
>>> string = """
... def function(param1, param2) -> None:
...     '''
...
...     :param param1: About param1.
...     :param param2: About param2.
...     :param param3: About param3.
...     '''
... """
>>> docsig(string=string, no_ansi=True)
2 in function
    SIG202: includes parameters that do not exist (params-do-not-exist)
1

A full list of checks can be found here

Message Control

If you have been using docsig prior to v0.56.0, please see updated messages

Documentation on message control

Classes

Documenting classes

pre-commit

docsig can be used as a pre-commit hook

It can be added to your .pre-commit-config.yaml as follows:

Standalone

repos:
  - repo: https://github.com/jshwi/docsig
    rev: v0.60.1
    hooks:
      - id: docsig
        args:
          - "--check-class"
          - "--check-dunders"
          - "--check-overridden"
          - "--check-protected"

or integrated with flake8

repos:
  - repo: https://github.com/PyCQA/flake8
    rev: "7.1.0"
    hooks:
      - id: flake8
        additional_dependencies:
          - docsig==0.60.1
        args:
          - "--sig-check-class"
          - "--sig-check-dunders"
          - "--sig-check-overridden"
          - "--sig-check-protected"

docsig's People

Contributors

dependabot[bot] avatar eford36 avatar jshwi avatar pre-commit-ci[bot] avatar snyk-bot 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

Watchers

 avatar  avatar

docsig's Issues

Import error on `sphinxcontrib.napoleon` on Python 3.10.8

Hey! I'm getting this ImportError when running docsig --help:

ImportError: cannot import name 'Callable' from 'collections'

docsig requires sphinxcontrb-napoleon directly, to its latest version of 0.7 which was released in 2018.

As seen in this commit to sphinxcontrib-napoleon, the issue I'm facing was fixed in 2021. I tried copy-pasting that commit into my venv and docsig --help ran correctly.

I see 2 alternatives:

  1. Given that napoleon now comes bundled with sphinx (at sphinx.ext.napoleon), docsig should have a direct requirement on sphinx. sphinx is quite big, though, and you may not want this.
  2. Specify a git dependency [ref] for sphinxcontrib-napoleon, knowing that that repo is not kept up to date.

I can work on a PR to fix this with whatever solution you prefer.

Handling of *args and **kwargs

Hello,

I'm not sure what's the convention of documenting *args and **kwargs but I think they are usually skipped.

What do you think about ignoring them (if they are not present in the docstring)?

remove click

remove click dependency which is not used in many places, and is not essential

use ansi codes instead and reduce excess dependencies

Issue with pre-commit integration

Hello @jshwi,

Trying to test this I found a bug related to the pre-commit configuration.

pre-commit-config.yaml

-   repo: https://github.com/jshwi/docsig
    rev: v0.33.0
    hooks:
      - id: docsig
        name: docsig
        entry: docsig
        language: system
        types: [python]
        require_serial: true
        args:
          - "-i"
          - "--ignore-kwargs"

I get an error: docsig: error: unrecognized arguments: --ignore-kwargs

Then I tried manually and the version wasn't the latest. After the manual update (pip install -U docsig), both manual and pre-commit worked.

This shouldn't be the case since I've specified the exact version in the pre-commit (I guess it should have it's own environment based on the yaml specification).

Can you check if this is due to bad integration?

Regarding the feature itself, everything seems to be working as expected so far. 🎉

Best, Lazar

docsig doesn't seem to support `@typing.overload`-ed functions/methods well

Hi,

Consider this code, modified from the typing docs to include a docstring:

from typing import overload

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    """process a response.

    :param response: the response to process
    :return: something depending on what the response is
    """
    ...  # actual implementation goes here
docsig checking code

from docsig import docsig
    
string_to_check = """
from typing import overload

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    \"\"\"process a response.

    :param response: the response to process
    :return: something depending on what the response is
    \"\"\"
    ...  # actual implementation goes here
"""
docsig(string=string_to_check)

This currently throws a bunch of docsig errors:

4
-
def process(✖response) -> ✓None:
    ...

E113: function is missing a docstring

7
-
def process(✖response) -> ✖tuple[None]:
    ...

E113: function is missing a docstring

10
--
def process(✖response) -> ✖str:
    ...

E113: function is missing a docstring

13
--
def process(✓response)?:
    """
    :param response: ✓
    :return: ✖
    """

E109: cannot determine whether a return statement should exist or not

But to my mind this is documented in a way that seems reasonable.

The fact that Sphinx supports this for rendering docstrings with autodoc/autosummary makes me think this is do-able (their code for supporting this is here), but it seems like this may significantly increase the complexity of docsig's docstring parsing code.

A couple of ways of opting out of supporting this for docsig:

  1. Document it as unsupported, don't change the default behaviour but allow comments like '# docsig off' that turn off docsig checks for a function
  2. Turn off all checks for overload-ed functions/methods, and document this. However, this still requires figuring out which functions/methods are overload-ed, which is still potentially a reasonable amount of work/change to the existing logic.

Report when the parameter is spelled wrongly

somemethod(myparam) -> str:
    """ What the method does
    :param nottherightparam: what the param does
    :return: str
    """

is not reported in version 0.13.0. However, if another mistake is added, e.g. I remove the return type hint and cause a E109, then the output shows that the parameter is wrong.

And a minor thing: docsig -v doesn't return anything, but docsig --version works

SIG401 false positive

Using an rst directive with an indent of 3 spaces can lead to a false positive regarding the indentation of params.
When using 4 spaces, this false positive does not appear.

Please note that 3-space indent style is the one preferred by docutils and sphinx docs also.
When nesting rst statements, you end up with unsightly/unpredicable results quickly if you try to enforce 4-space indentation.

def method(*, arg1 = "") -> str:
    """
    Description text

    .. code-block:: python
       print()

    :param arg1: text
    :return: text
    :raises TypeError: Incorrect argument(s)
    """
    return ""

Expected: no error

Environment:

  • Python version: 3.11.6
  • docsig version: 0.60.0

Enhancement suggestion: Add capability to check __init__ document in its own docstring

Firstly, thanks for docsig, it's great!

One area where I still am finding 'mistakes' in my docstring signatures though is where I've added the description of an __init__ signature in the __init__ docstring itself, rather than the class docstring. If I miss a parameter, or document a parameter that doesn't exist there, there's no way to configure docsig to raise an error, without it also being unhappy about the signature being documented in the __init__ docstring rather than the class docstring.

Minimal example

I think this is understood that this isn't covered (it's on the README page), so putting this inside a 'details' as I think my job here is more persuading that it's worth docsig supporting this, rather than describing what it currently does - but I want to have that too of course.

For a minimal example, consider this code:

class SomeClass:
    \"\"\"This class does something useful.\"\"\"

    def __init__(self, first_arg: bool, second_arg: str):
        \"\"\"Create a new instance of SomeClass
        
        :param first_arg: this does exist
        :param non_existent_arg: this arg doesn't actually exist!
        \"\"\"
        pass

This has incorrect documentation (so rendered docs will show incorrectly), but will pass a docsig check with default configuration):

from docsig import docsig
    
string_to_check = """
class SomeClass:
    \"\"\"This class does something useful.\"\"\"

    def __init__(self, first_arg: bool, second_arg: str):
        \"\"\"Create a new instance of SomeClass
        
        :param first_arg: this does exist
        :param non_existent_arg: this arg doesn't actually exist!
        \"\"\"
        pass
"""

docsig(string=string_to_check, check_class=True)

Note though that if I turn on check_class, even a correctly documented __init__ will cause an error E103: parameters missing:

from docsig import docsig
    
string_to_check = """
class SomeClass:
    \"\"\"This class does something useful.\"\"\"

    def __init__(self, first_arg: bool, second_arg: str):
        \"\"\"Create a new instance of SomeClass
        
        :param first_arg: this does exist
        :param second_arg: this exists too and completes coverage
        \"\"\"
        pass
"""

docsig(string=string_to_check, check_class=True)

this gives:

5 in SomeClass
--------------
class SomeClass:
    """
    :param None: ✖
    :param None: ✖
    """

    def __init__(✖first_arg, ✖second_arg)?:

E103: parameters missing

However, I think this is a valid way of writing docstrings, and one where docsig would add value if it checked this style of writing them (I found this by realising I had made a mistake of this kind in my project).

In fact, my reading of PEP257's multi-line docstring section is that this is the recommended way of writing __init__ signatures:

The class constructor should be documented in the docstring for its __init__ method

From this paragraph on docstrings for classes:

The docstring for a class should summarize its behavior and list the public methods and instance variables. If the class is intended to be subclassed, and has an additional interface for subclasses, this interface should be listed separately (in the docstring). The class constructor should be documented in the docstring for its __init__ method. Individual methods should be documented by their own docstring.

I think probably for backwards-compatibility, we would probably want to leave the check of an __init__ docstring only running when check_class is True.

Would you be interested in docsig supporting this?

If so, I may be able to work on a PR myself, if we can agree on an approach.

Some initial thoughts on supporting this

My impression is that it's [these lines](https://github.com/jshwi/docsig/blob/7fc0f02c71f8cb469c41763dee2ccf0bba2f6e38/docsig/_function.py#L292-L295) (copied below for inline clarity that set the docstring of `__init__` method's to the parent class's docstring, which prevents this being possible:

        self._docstring = _Docstring(
            node.doc_node if not self.isinit else self._parent.doc_node,
            ignore_kwargs,
        )

There's a couple of approaches that I wonder if they're worth considering:

  1. allow the constructor(/__init__) of _function._Docstring to take a str for node, as well as _ast.Const or None, and then replace:
    node.doc_node if not self.isinit else self._parent.doc_node,
    with:
    node.doc_node if not self.isinit else self._parent.doc_node.value + "\n" + node.doc_node.value,
    This will fix the problems I currently have, but does allow weird things where some params are documented in the class docstring, and others in the __init__ docstring, which is undesirable, but seems unlikely to happen.
  2. Add a class method on _function._Docstring to create a _Docstring from a string, which the above code will call in the self.isinit case (this preserves the constructor signature of _Docstring but is otherwise similar to the above
  3. Move the if not self.isinit logic inside _Docstring.__init__, create _Matches(...) for both the __init__ docstring and the parent class docstring, and use whichever one gets matches for the _Docstring._string, _Docstring._args and _Docstring._returns. If neither, choose the class docstring, if both match maybe raise an error? Might have to be a new one. The downside of this is that it's a bigger change, and there's more compute involved in deciding which docstring to use for __init__ methods, which is then 'throwaway work' if check_class isn't even true.

sort checked paths

check paths in order of name

this can allow for more accurate expectations

args and kwargs are not recognized as generic arguments

Hi,

I just came across an error (or expected behavior?):

I have the Fuction with the docstring

def mocked_requests_get(*args: str, **kwargs: str) -> Response:
    """Mock the expected Response from the API based on the received url via args.

    Returns
    -------
    Response
        response object
    """

which leads to the Error:

def mocked_requests_get(✖*args, ✖**kwargs) -> ✓Response:
    """
    :param None: ✖
    :param None: ✖
    :return: ✓
    """
E103: parameters missing

Not sure if this should be the case usually I would not annotate args/kwargs as they are no specific function arguments. Or is my notion wrong here?

We are using numpy type docstrings in case this is relevant. Happy to provide more info if I forgot anything relevant.

Feature request - pre-commit integration & links

Feature request

I realy like this library and find that it has some features that are missing in the pydocstyle. 🎉

Feature 1 🚀

Since many users automate linters, it would be nice to have support for the pre-commit. :)

Feature 2 🚀

When path to a file is displayed, it would be nice if it was a link to the specific line (like in pydocstyle). I'm using PyCharm if that's of any relevance.

exclude cannot handle directory

The exclude files cannot hold the whole dictionary. The regex pattern checks only for the name of the file so in a case that you have 2 similar file names but in different folders then you have to exclude both.

Replace bug:
In my case I'm using poetry so the config file looks like this:
pyproject.toml

[tool.docsig]
exclude = '''.*src\\design\\.*'''

The design folder should be excluded. But it is not. This line makes nothing.

Expected:
The whole folder is not in checks.

Possible solution:
right now in _files.py::Paths::_populate there is a regex match _re.match(i, root.name) and to proper work it should be a _re.match(i, str(name)) This will allows to check whole folders instead of only one file. It is really important if you have the same names in different folders and only one should be excluded.

Environment:

  • Python version: 3.11.4
  • docsig version: 0.59.1

Sphinx 7.0 compatibility

Hi,

At the moment, docsig declares a dependency of:

Sphinx = ">=4.3.2,<7.0.0"

which means you can't install docsig in the same virtual environment as a project that wants to build it's own docs with Sphinx 7.0 or greater.

However, from a quick look, it doesn't seem like it needs to rule out 7.0.0 for the correct operation of docsig - the only place I can see sphinx used from a quick search is as import sphinx.ext.napoleon as _s in docsig/_function.py, and even there, it's the Napoleon extension specifically, and it doesn't look to me that the way it's used would be broken by 7.0.

I'm guessing you want to restrict to <7.0.0 for building the docs of docsig, but could that be done as a dev dependency, and the 'main' dependency just be Sphinx = >=4.3.2` or similar?

This isn't affecting me directly (it was, but I just changed my pre-commit config so docsig got installed in its own virtual environment rather than as a 'local' hook, which is best practice anyway).

Let me know what you think, and if you think there is work (beyond the normal testing of PRs etc.) to support sphinx 7, I can potentially pick it up

Skip checking for one line docstings

Hello,

It would be good if checking could be skipped somehow for one line docstrings.

For example

def example(some_input: int) -> int:
    """Return input."""
    return some_input

Sometimes the effort to write the full doctoring is just too high. This is also fine with the linter pydocstyle.

Would you consider adding an option to ignore docstrings that are in one line?

Second layer defined functions seem not to be checked

Hi @jshwi,

we are using docsig for quite a while now to check our code documentation and we are very happy with the tool. However, we have observed that it seems not to check second layer defined functions. In same cases one could think about such scenarios where functions are defined only under certain conditions. Examples of code that could be imagined:

def my_function(argument: int = 42) -> int:
    """
    Function that prints a message and returns the argument + 1

    Parameters
    ----------
    argument : int, optional
        The input argument, by default 42

    Returns
    -------
    int
        The input argument + 1
    """
    print("Hello from a function")
    print(argument)
    return argument + 1


if True:
    my_function(42)
    def my_external_function(argument: int = 42) -> int:
        print("Hello from an external function")
        print(argument)
        return argument + 42

or

def my_function(argument: int = 42) -> int:
    """
    Function that prints a message and returns the argument + 1

    Parameters
    ----------
    argument : int, optional
        The input argument, by default 42

    Returns
    -------
    int
        The input argument + 1
    """
    print("Hello from a function")
    print(argument)
    def my_external_function(argument: int = 42) -> int:
        print("Hello from an external function")
        print(argument)
        return argument + 42
    return argument + 1```

I would like to ask if this is expected behavior and if so if there are any plans to also check other layers than the first one? For us this would be really helpful 😃

Thanks in advance and Best
Conrad

flake8 plugin

docsig as a flake8 extension

docsig can be integrated with a flake8 workflow

more flexibility as to how docsig can be used

Support for Python 3.7.x

Hey @jshwi! I came across this tool because of a comment of yours on StackOverflow. I wanted to use your tool for a small project that I'm currently working on, but poetry cannot resolve the dependencies because my tool is built for Python 3.7.2+, and yours for 3.8+.

Is there a reason for not to support Python 3.7? If so, is there anything I can do to help add support for it?

List instead of regex

Right now for excluding the files it is required to use regex. For the other tools like flake8 the exclude contain a list of paths which should be excluded.
The regex is really difficult to read write and also it is hard to hold it inside the .toml file. The regex pattern contains also \, \\, \/ which are not allowed in a config files, you have to makes workaround for it. Also the regex is not the best option for the paths.

The solution can be a list which holds a paths and also file names. Then it easy to read and it is definitely more user friendly.
Example: excluded=["src/design/*", "docs/*", "src/my_file.py"]

Parameter and return value is not correctly recognized

Hey I just came across the project and would love to use it for larger projects to avoid faulty documentation after e.g. refactoring of code.
Now I have a function:

def modify(numericString: Union[str, int]) -> str:
    '''Do stuff.

    Parameters
    ----------
    numericString: Union[str, int]
        numeric string that should be converted.

    Returns
    -------
    str
        reformatted string
    '''
    numericString = str(numericString)
    last = numericString[-1]
    middle = numericString[-3:-1]
    first = numericString[:-3]
    finalstring = "-".join([first, middle, last])
    return finalstring 

Now I get the error:

def modify(✖numericString) -> ✓str:
    """...

    :param None: ✖
    :return: ✓
    """

E103: parameters missing

Another example I encountered:

def check_stuff(str_lin: str) -> bool:
    """Check if "A" or "B".

    The function checks wether the string is "A" or "B".

    Parameters
    ----------
    str_lin: str
        special string produced by function_of_y

    Returns
    -------
    bool
        Returns True, else false
    """
    if any(s in str_lin for s in ["A", "B"]):
        return True
    return False

The error:

def check_stuff(✖str_lin) -> ✖bool:
    """...

    :param None: ✖
    :return: ✖
    """

E103: parameters missing
E105: return missing from docstring

I am a bit confused as I cannot really pinpoint the issue. Is this a parsing or formatting problem of the docstring? Any obvious error here?
Please ignore the random weird functions, they are just examples similar to conde I have written.

v0.59.0 fails with UnicodeDecodeError

Hey, thanks for providing this cool tool!

Our github workflow utilzes docsig and so far, it worked smoothly. After upgrading to 0.59.0 we get this error:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

You can the the original error here

Since it worked so far, I guess this is a bug. Unfortunately, I cannot test this locally right now, so I am not able to find a minimal example.
I hope I can provide this in the next days.

Environment:

  • Python version: 3.11.9
  • docsig version: 0.59.0

Positional-only arguments not recognized

Thank you for this fantastic tool!

I am using it to validate and correct existing docstrings. I found an issue I can't seem to overcome, though, related to the use of positional-only arguments.

For example, given this function and docstring...

def starmap(
    self,
    fun: Callable[..., Any],
    iterable: Sequence[Sequence[Any]],
    /,
    *args: Any,
    timeout: float = 0,
    show_progress: bool | None = None,
    **kwargs: Any,
) -> list[Job]:
    """Submits many jobs to the queue -- one for each sequence in the iterable. Waits for all to finish, then returns the results.

    Args:
        fun: ...
        iterable: ...
        *args: static arguments passed to the function.
        timeout: ...
        show_progress: ...
        **kwargs: static keyword-arguments passed to the function.

    Returns:
        ...
    """

...I cannot overcome this error reported by docsig:

---------------------------------
def starmap(✖*args, ✖timeout, ✖show_progress, ✖**kwargs, ✖None, ✖None) -> ✓list[Job]:
    """
    :param fun: ✖
    :param iterable: ✖
    :param args: ✖
    :param timeout: ✖
    :param show_progress: ✖
    :param kwargs: ✖
    :return: ✓
    """

E102: includes parameters that do not exist
E101: parameters out of order

`@typing.overload`-ed methods not supported

Following on from #196 - sorry, I probably should have highlighted methods as important to me.

When docsig checks the following code:

class SomeClass:

    @overload
    def process(self, response: None) -> None:
        ...
    @overload
    def process(self, response: int) -> tuple[int, str]:
        ...
    @overload
    def process(self, response: bytes) -> str:
        ...
    def process(self, response):
        """process a response.

        :param response: the response to process
        :return: something depending on what the response is
        """
        ...  # actual implementation goes here

I get the following error:

no_vc/test_docsig_methods.py:12 in SomeClass
--------------------------------------------
def process(✖None) -> ✓str:
    """
    :param response: ✖
    :return: ✓
    """

E102: includes parameters that do not exist

I had a go debugging and think I've tracked down the issue:

inserting:

                        if func.name == "process":
                            breakpoint()

just before this line

and then running subnode.args.arguments shows that the self argument isn't prevent, as it appears to be for a non-overload-ed method:

debugging session:

> docsig/_module.py(61)__init__()
-> func = _Function(
(Pdb) subnode.args.arguments
[<AssignName.response l.12 at 0x1058eeb80>]
(Pdb) 

Then, when creating the _Signature, docsig pops the first argument if the relevant function is a (non-static) method, which in this case is the 'actual' first argument response.

Optinal return statements with overload function result in docsig error E104

Hi @jshwi,

we have again found a (from our perspective) weird behavior of docsig. The issue occurs when we define different return types with overload functions. I have prepared a minimal example:

from typing import Optional, overload


@overload
def get_something(number: int) -> str:
    """For getting a string from an integer."""


@overload
def get_something(number: None) -> None:
    """For getting a string from an integer."""


def get_something(number: Optional[int]) -> Optional[str]:
    """
    For getting a string from an integer.

    Parameters
    ----------
    number : int
        The number to convert to a string.

    Returns
    -------
    str
        The string representation of the number.
    """
    if number is None:
        return None
    return str(number)

We call docsig with the following command: docsig -C -m -N -o -p -P test.py

Perhaps you can comment on that. We think that no error in that case should be raised.

Thanks in advance and Best
Conrad

Nothing is shown after docsig .

Hi, I'm testing this package on my code with docsig . and I get nothing back. Literally nothing. I'm using Sphinx's docstring format on my code. Is there some way to debug this?

Environment:

  • Python version: 3.10.14
  • docsig version: 0.54.1

False positive when return annotation is a string

Hello,

Here's a minimal example:

def example(some_input: int) -> int:
    """
    Do something.

    Args:
        some_input: Random integer

    Returns:
        Unchanged input
    """
    return some_input

This works like a charm but, when the return type is 'int' following error is returned. Sometimes, the return type has to be represented as a string due to dependency issues.

def example(✓some_input) -> ✖None:
    """
    :param some_input: ✓
    :return: ✖
    """

E104: return statement documented for None

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.