Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yields section requires wrong type annotation #75

Closed
haakonvt opened this issue Aug 23, 2023 · 7 comments
Closed

Yields section requires wrong type annotation #75

haakonvt opened this issue Aug 23, 2023 · 7 comments

Comments

@haakonvt
Copy link

For a generator (function) like the following, according to the Google style docs, the annotation in the Yields: section should be annotated as follows:

from typing import Generator


def foo(n: int) -> Generator[int, None, None]:
    """Description

    Args:
        n (int): Description

    Yields:
        int: Description
    """
    yield from range(n)

This throws an error when I try to run it through pydoclint:

4: DOC404: Function `foo` yield type(s) in docstring not consistent with the return annotation.
  Return annotation types: ['Generator[int, None, None]']; docstring return section types: ['int']

I.e., it wants:

    Yields:
        Generator[int, None, None]: Description

Is this a bug?

@erlendvollset
Copy link

All of these docstring/type-annotation combinations for this function are valid and should be allowed:

from typing import Generator, Iterator


def foo(n: int) -> Generator[int, None, None]:
    """Description

    Args:
        n (int): Description

    Yields:
        int: Description
    """
    yield from range(n)

def foo2(n: int) -> Generator[int, None, None]:
    """Description

    Args:
        n (int): Description

    Returns:
        Generator[int, None, None]: Description
    """
    yield from range(n)

def foo3(n: int) -> Iterator[int]:
    """Description

    Args:
        n (int): Description

    Yields:
        int: Description
    """
    yield from range(n)

def foo4(n: int) -> Iterator[int]:
    """Description

    Args:
        n (int): Description

    Returns:
        Iterator[int]: Description
    """
    yield from range(n)

@jsh9
Copy link
Owner

jsh9 commented Aug 24, 2023

Hi @haakonvt , thank you for discovering this! It's indeed a bug, and it's fixed in v0.2.3.

@jsh9
Copy link
Owner

jsh9 commented Aug 24, 2023

Hi @erlendvollset , thank you for providing those examples!

My fix addresses the 1st combination:

def foo(n: int) -> Generator[int, None, None]:
    """Description

    Args:
        n (int): Description

    Yields:
        int: Description
    """
    yield from range(n)

The 2nd combination you mentioned above is a very interesting idea. I'll need to think about how to implement it though. (And if it "interferes" with existing violation checking logic, I may choose not to implement it.)

As to the 3rd and the 4th combinations, please read this note that I wrote: https://jsh9.github.io/pydoclint/notes_generator_vs_iterator.html

@haakonvt
Copy link
Author

Hi @haakonvt , thank you for discovering this! It's indeed a bug, and it's fixed in v0.2.3.

Great, thanks (again x3) 😄

@haakonvt
Copy link
Author

@jsh9 Just updated, worked for all cases except one which reports a DOC404:

5: DOC404: Method `Foo.create` yield type(s) in docstring not consistent with the return
  annotation. The yield type (the 0th arg in Generator[...]): Generator[tuple[float, ...], None, None];
  docstring "yields" section types: tuple[float, ...]

The code that triggered it:

from typing import Generator

class Foo:
    def create(self, n: int) -> Generator[tuple[float, ...], None, None]:
        """Foo

        Args:
            n (int): Description.

        Yields:
            tuple[float, ...]: Description.
        """
        yield from ((*self.bar, i) for i in range(self.baz))

@jsh9
Copy link
Owner

jsh9 commented Aug 24, 2023

Yep, I just realized that issue too. I fixed it in v0.2.4.

@jsh9
Copy link
Owner

jsh9 commented Aug 28, 2023

Hi @erlendvollset and @haakonvt :

I released v0.3.0, which allowed this combination in your example:

def foo3(n: int) -> Iterator[int]:
    """Description

    Args:
        n (int): Description

    Yields:
        int: Description
    """
    yield from range(n)

See this issue (#76) for more details.

@jsh9 jsh9 closed this as completed Aug 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants