-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Can't index named tuple by defined constant #3078
Comments
A simple fix would be to allow any indexing on NamedTuples and return Any. That would have some false negatives, but I feel like those are unlikely in real code. |
The type information is available in But of course |
(Obviously related to singleton types; #3062) |
The type of from typing import *
A = NamedTuple('A', [('x', int), ('y', str)])
X = 0
Y = 1
a = A()
reveal_type(a[0]) # int
reveal_type(a[1]) # str
reveal_type(a[X]) # expected int, but get an error
reveal_type(a[Y]) # expected int, but get an error |
But if the type of X was the singleton type |
Ah right of course, it's the value of If we end up using If we don't have The initial assignment should be enough, since we obviously won't support this:
|
It's an interesting change to mypy's architecture. I also worry about how mypy would tell that ST_MODE is meant to be a constant -- there's no Python syntax to distinguish between a constant and e.g. a global counter, and the naming convention (UPPER_CASE for constants) is pretty weak and feels unreliable. |
Can mypy assume it's a constant if the variable (properly qualified of course) is assigned (or augmented assigned) to only once across the entire codebase? Edit: assigned to only once, and never augmented assigned I meant. |
It feels like we are trying to reinvent abstract interpretation, |
Well, both local and global variables are ok. I think mypy would know whether a class attribute is ever modified in the codebase (because it keeps track of object type, and modifying a class attribute requires the base of the member access to be of that type). That instance attributes. Maybe just not consider them as constants, ever? I think there are fewer use cases where someone needs to access named tuples fields using instance attributes. |
@pkch Mypy often doesn't see the entire codebase (due to stubs, skipped modules, etc.) so it can't decide whether something is assigned to only once reliably. More importantly, mypy does no whole-program reasoning because it makes incremental checking really hard and can result in undesirable spooky-action-at-a-distance behavior. |
In that case, maybe we should allow some syntax to declare a constant? |
That would probably the best way to do this. This actually comes up pretty frequently, so it might be a feature worth considering. A new syntax may require a PEP 484 change in order for it to be usable in stubs, which makes adoption harder. Here are some ideas for the syntax:
Here's another alternative that I don't like:
I'm not yet convinced that this is a high-priority feature, but it might be worthwhile to have eventually. |
I kind of like x: Final = 0
y: Final[int] = 0 With fallbacks using @ilevkivskyi Would it be absolutely necessary to make changes to typing.py for this? Couldn't it live in mypy_extensions.py? |
I don't see any strong reasons to put it in There is another point that comes to my mind: If we will have several things only in |
I think of mypy_extensions as a way to have quicker turn-around for things that ought to go in typing, in addition to a place where experiments or extensions that will always be mypy-specific go. In my ideal world everything in mypy_extensions would eventually go into typing, but having it in mypy_extensions would provide a backwards compatible solution for people who need to be portable to old 3.5 or 3.6 versions. So the issue you bring up will exist, but it's acknowledged that it's a temporary solution. |
This is now supported with literal types. |
Example:
There's a real-world use case for this: the
stats
stdlib module defines constants likeST_MODE
that are supposed to be used as indices intoos.stat_result
(which was turned into a NamedTuple in python/typeshed#1103).The text was updated successfully, but these errors were encountered: