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

Strange error message with variable type annotation #2398

Closed
graingert opened this issue Nov 4, 2016 · 11 comments
Closed

Strange error message with variable type annotation #2398

graingert opened this issue Nov 4, 2016 · 11 comments
Labels

Comments

@graingert
Copy link
Contributor

graingert commented Nov 4, 2016

from typing import NewType

Ticker = NewType('Ticker', str)
SecurityID = NewType('SecurityID', str)


SYMBOLS = {
    'ham': '4a24ab25-766d-4d6c-99e2-337da6d0ba45',
    'spam': 'e8248888-b413-4def-b11a-763b10faf9c0',
}  # type: Dict[Ticker, SecurityID]

INDICES = {
    'eggs',
    'mayo',
}  # type: Set[Ticker]

TICKERS = INDICES | SYMBOLS.keys() # type: Set[Ticker]

Results in:

s.py:7: error: List item 0 has incompatible type "Tuple[str, str]"
s.py:7: error: List item 1 has incompatible type "Tuple[str, str]"
s.py:12: error: Argument 1 to <set> has incompatible type "str"; expected "Ticker"
s.py:12: error: Argument 2 to <set> has incompatible type "str"; expected "Ticker"
@graingert
Copy link
Contributor Author

graingert commented Nov 4, 2016

If you remove the comments, everything is checked as Any and works fine.

@graingert graingert changed the title Strange error message with lowercase type annotation Strange error message with variable type annotation Nov 4, 2016
@graingert
Copy link
Contributor Author

Where's the List? where's the Tuple[str, str] coming from?

@gvanrossum
Copy link
Member

The List and Tuple are coming from the translation mypy does from dict literals to a call to the dict() function. It is type-checking the translated version, which is something like dict([(key1, value1), (key2, value2), ...]). There's an existing issue about that: #304.

The reason you are getting type errors here is that you can't use string literals where a Ticker or SecurityId is expected. This version is clean:

SYMBOLS = {
    Ticker('ham'): SecurityID('4a24ab25-766d-4d6c-99e2-337da6d0ba45'),
    Ticker('spam'): SecurityID('e8248888-b413-4def-b11a-763b10faf9c0'),
}  # type: Dict[Ticker, SecurityID]

INDICES = {
    Ticker('eggs'),
    Ticker('mayo'),
}  # type: Set[Ticker]

@rwbarton
Copy link
Contributor

rwbarton commented Nov 4, 2016

Indeed, the purpose of NewType is exactly to prevent code like this from type checking.

@graingert
Copy link
Contributor Author

@gvanrossum do you think for literals a cast is nicer?

from typing import NewType, cast

Ticker = NewType('Ticker', str)
SecurityID = NewType('SecurityID', str)


SYMBOLS = cast(Dict[Ticker, SecurityID], {
    'ham': '4a24ab25-766d-4d6c-99e2-337da6d0ba45',
    'spam': 'e8248888-b413-4def-b11a-763b10faf9c0',
})

INDICES = cast(Set[Ticker], {
    'eggs',
    'mayo',
})

TICKERS = INDICES | SYMBOLS.keys() # type: Set[Ticker]

@gvanrossum
Copy link
Member

No, cast() doesn't check anything -- it would let through non-strings without errors.

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 4, 2016

This would be type safe:

_SYMBOLS = {
    'ham': '4a24ab25-766d-4d6c-99e2-337da6d0ba45',
    'spam': 'e8248888-b413-4def-b11a-763b10faf9c0',
}
SYMBOLS = {Ticker(ticker): SecurityID(id) for ticker, id in _SYMBOLS.items()}
del _SYMBOLS

@graingert
Copy link
Contributor Author

graingert commented Nov 4, 2016

@JukkaL that's nicer than putting the NewType on each item, but it's still not very elegant

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 4, 2016

If you want to use NewType, you almost always have to write some extra code. The extra type checking precision doesn't come for free.

@graingert
Copy link
Contributor Author

@JukkaL I think this usecase is worth a syntactical shortcut, as quite often when you want to use a dict as a table of data it will benefit from NewType

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 4, 2016

Feel free to suggest a better syntax (please create a new issue, as this was closed).

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

4 participants