Skip to content

Allow non-literals when indexing uniform tuples #899

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
JukkaL opened this issue Oct 10, 2015 · 3 comments
Closed

Allow non-literals when indexing uniform tuples #899

JukkaL opened this issue Oct 10, 2015 · 3 comments
Labels
bug mypy got something wrong

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 10, 2015

Currently mypy doesn't allow indexing fixed-length tuples using a non-literal index. We should probably support this at least for tuples with homogeneous types.

For example, code like this should probably be okay:

t = (1, 3, 7)
for i in range(len(t)):
    print(i, t[i])

The example below is actually already valid so rejecting the above code is inconsistent (this works due to how we set the fallback attribute for tuples to be Tuple[t, ...]):

t = (1, 2, 3)
for i, x in enumerate(t):
    print(i, x)
@JukkaL JukkaL added the bug mypy got something wrong label Oct 10, 2015
@JukkaL
Copy link
Collaborator Author

JukkaL commented Oct 10, 2015

The relevant bit of code is visit_index_expr_helper in mypy/checkexpr.py.

@o11c
Copy link
Contributor

o11c commented Oct 10, 2015

I think there's a good argument for allowing it for all tuples, just with a return type of Union[T, U, V...].

Rather than forcing the error immediately, let the error be deferred if necessary.

gnprice pushed a commit that referenced this issue Jun 3, 2016
Also fix the defaults for start, end, and stride to `None` to correctly match the Python slice semantics -- in particular, if the stride is negative then the default start and end are effectively `length - 1` and `0` respectively rather than vice versa.

Fixes #886, except for the part that's been separated out as #899.
@momandine
Copy link

I had a generator expression that constructed a tuple, that I knew from context would be of length 3

self.tpl = tuple(int(x) for x in some_string.split('.'))  # type: Tuple[int, int, int]

And then later __getitem__ that indexed into the tuple

def __getitem__(self, key):
    # type: (int) -> int
    return self.tpl[key]  

There were two mypy errors:

error: Incompatible types in assignment (expression has type Tuple[int, ...], variable has type "Tuple[int, int, int]")
error: Tuple index must be an integer literal

The first is easier to understand, the latter I found very confusing because it went away as soon as I typed the tuple-generator exception without a specific length, e.g. Tuple[int, ...]. Why would indexing into a less-specific tuple be ok but a fixed-length one bad?

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

No branches or pull requests

3 participants