Skip to content

converter expected to return a Tuple where perhaps an Iterable should do #474

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

Closed
wsanchez opened this issue Dec 19, 2018 · 8 comments
Closed
Labels

Comments

@wsanchez
Copy link

After updating mypy from 0.630 to 0.650 for Klein, I get this error:

src/klein/_headers.py:172:18: error: Argument "converter" to "attrib" has incompatible type "Callable[[Iterable[Iterable[bytes]]], Sequence[Tuple[bytes, bytes]]]"; expected "Optional[Callable[[Any], Tuple[]]]"

If I'm reading this correctly, the provided converter is a Callable (OK) and takes one argument (OK) and returns a Sequence (not OK: Tuple expected).

The converter specified in src/klein/_headers.py:172 is normalizeRawHeadersFrozen:

def normalizeRawHeadersFrozen(headerPairs):
    # type: (Iterable[Iterable[bytes]]) -> RawHeaders
    return tuple(normalizeRawHeaders(headerPairs))

This implementation does return a tuple, but I wanted to limit my commitment to a Sequence. I think that converter should be happy with a Sequence in practice, so I'd like to lobby for a looser requirement here.

@wsanchez wsanchez added the Bug label Dec 19, 2018
@wsanchez
Copy link
Author

Hrm. I'm realizing that there's no way that attrs is requiring a Tuple here so this has to be in my code…?

@hynek
Copy link
Member

hynek commented Dec 19, 2018

I suppose the answer is to play with mypy's reveal_type()?

@wsanchez
Copy link
Author

I'm not having any luck… Here's a simpler example:

from typing import Iterable, Sequence, Tuple
from attr import attrib, attrs

RawHeader = Tuple[bytes, bytes]
RawHeaders = Sequence[RawHeader]

def normalizeRawHeadersFrozen(headerPairs):
    # type: (Iterable[Iterable[bytes]]) -> RawHeaders
    return tuple()

@attrs(frozen=True)
class Test(object):
    rawHeaders = attrib(
        converter=normalizeRawHeadersFrozen,
        default=(),
    )  # type: RawHeaders

reveal_type(RawHeaders)
reveal_type(normalizeRawHeadersFrozen)
reveal_type(Test.rawHeaders)

And mypy outputs:

test.py:13: error: Argument "converter" to "attrib" has incompatible type "Callable[[Iterable[Iterable[bytes]]], Sequence[Tuple[bytes, bytes]]]"; expected "Optional[Callable[[Any], Tuple[]]]"
test.py:18: error: Revealed type is 'def () -> typing.Sequence[Tuple[builtins.bytes, builtins.bytes]]'
test.py:19: error: Revealed type is 'def (headerPairs: typing.Iterable[typing.Iterable[builtins.bytes]]) -> typing.Sequence[Tuple[builtins.bytes, builtins.bytes]]'
test.py:20: error: Revealed type is 'typing.Sequence[Tuple[builtins.bytes, builtins.bytes]]'

What I don't get is why it thinks that converter should return a Tuple, rather than a Sequence, given that the attribute's type is Sequence[Tuple[bytes, bytes]].

@hynek
Copy link
Member

hynek commented Dec 29, 2018

Sounds like a case for the typing crew. :)

@euresti
Copy link
Contributor

euresti commented Dec 29, 2018

What version of mypy are you running? I'm not seeing that error in the latest master.

Aha. Doing a git bisect i see this was fixed by python/mypy#6006

@wsanchez
Copy link
Author

Oh, great! Thanks for finding that @euresti.

@wsanchez
Copy link
Author

Closing here.

@hynek
Copy link
Member

hynek commented Jan 2, 2019

Yay SEPs. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants