Skip to content

Incorrect errors for fstrings + generators #3385

Closed

Description

@ns-cweber

mypy version: 0.511
python version: 3.6.1

Given this valid program:

from typing import Iterator

def stringify(it: Iterator[int]) -> Iterator[str]:
    return (f"{x}" for x in it)

def stringify2(it: Iterator[int]) -> Iterator[str]:
    for x in it:
        yield f"{x}"

def stringify3(it: Iterator[int]) -> Iterator[str]:
    return (str(x) for x in it)

def stringify4(it: Iterator[int]) -> Iterator[str]:
    for x in it:
        yield str(x)

I get errors for the first two variations:

foo.py:4: error: Generator has incompatible item type "int"
foo.py:8: error: Incompatible types in yield (actual type "int", expected type "str")

It seems that mypy doesn't recognize that fstrings are produce a str. Interestingly, the yield error didn't show up in my old mypy version 0.501.

Activity

  1. ns-cweber commented on May 19, 2017

    @ns-cweber
    Author

    Strangely, this is fine:

    def stringify5(it: Iterator[Tuple[int, int]]) -> Iterator[str]:
        return (f"({x}, {y})" for x, y in it)

    ... but this is not:

    class Point:
        def __init__(self, x, y) -> None:
            self.x = x
            self.y = y
    
        def __str__(self) -> str:
            return f"({self.x}, {self.y})"
    
    def stringify6(it: Iterator[Point]) -> Iterator[str]:
        return (f"{pt}" for pt in it)

    So it seems like it's the unpacking syntax (... for x, y in ...) that makes the difference, and not whether or not the iterator type is primitive.

  2. changed the title [-]Incorrect errors for new fstrings[/-] [+]Incorrect errors for fstrings + generators[/+] on May 19, 2017
  3. ns-cweber commented on May 19, 2017

    @ns-cweber
    Author

    It looks like it doesn't have anything to do with the unpacking; it seems to pertain to the handling of ast.FormattedValue. Mypy handles this correctly:

    def stringify(it: Iterator[int]) -> Iterator[str]:
        return (f"asdf {x}" for x in it)

    According to GreenTreeSnakes' FormattedValue docs:

    If the string contains a single formatting field and nothing else the node can be isolated otherwise it appears in JoinedStr.

    In this most recent example, using an fstring with tokens besides the formatted value produces a JoinedStr token. Maybe mypy handles JoinedStr correctly but not FormattedValue?

  4. JelleZijlstra commented on May 19, 2017

    @JelleZijlstra
    Member

    Yes, it looks like the bug is that mypy interprets f"{x}" as having the type of x.

  5. added 2 commits that reference this issue on May 21, 2017
    3a37e18
    9e22c0c
  6. added a commit that references this issue on May 30, 2017
    d4864a9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions