You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MyPy disallows Tuple to be instantiated with variable number of items #8758
Tuple in Python - is a fixed-length list ("frozen list"). But there's nothing in Python that prevents same-name Tuple to be instantiated with different number of items (which may well be based on some condition)...
I have an issue related to mypy, conditional import and validation of the __all package attribute (defined as a Tuple containing variable number of items depending on the success of the conditional import). Consider following within package's init.py:
try:
from .__version__ import version as __version__
__all__ = (
'...........',
'...........',
'...........',
'__version__'
)
except ImportError:
__all__ = (
'...........',
'...........',
'...........'
)
When this code is checked by mypy, it raises following error:
______________________________ units/__init__.py _______________________________
15: error: Incompatible types in assignment (expression has type "Tuple[str, str, str]", variable has type "Tuple[str, str, str, str]")
_________________________________ test session _________________________________
mypy exited with status 1.
=============================== warnings summary ===============================
This issue keeps me from building Python package in the presence of 'mypy' check; I had to explicitly disable mypy check in order to build this package.
I'd like to have mypy recognize possibility of variable-size Tuple in the presence of conditional import (and in general - same-name Tuple can be instantiated having different size depending on some conditions), or be able to ignore this error (unfortunately, mypy output does not report error number that can be ignored), or entirely exclude given file from mypy check (similarly to flake8's "exclude" in the setup.cfg).
You can work around this by adding an explicit annotation of Tuple[str, ...]. I guess mypy could implicitly infer such a type for code like the above, but that runs into issues like #1026.
You can work around this by adding an explicit annotation of Tuple[str, ...]. I guess mypy could implicitly infer such a type for code like the above, but that runs into issues like #1026.
=================================== FAILURES ===================================
______________________________ units/__init__.py _______________________________
16: error: Name '__all__' already defined on line 9
_________________________________ test session _________________________________
mypy exited with status 1.
Tried that, too - which brings back to the initial error:
try:
from .__version__ import version as __version__
__all__: Tuple[str, str, str, str] = (
'.......',
'.......',
'.......',
'__version__'
)
except ImportError:
__all__ = (
'.......',
'.......',
'.......'
)
Error:
=================================== FAILURES ===================================
______________________________ units/__init__.py _______________________________
17: error: Incompatible types in assignment (expression has type "Tuple[str, str, str]", variable has type "Tuple[str, str, str, str]")
_________________________________ test session _________________________________
mypy exited with status 1.
@vpogrebi This is not a mypy bug, the tuple infers the first type it encounters when assigned to, and assigning a different type (with different amount of items inside the tuple) later on is an error - this is valid behavior. You need to explicitly tell it to either accept a variable amount of items via Tuple[str, ...], allow redefinition via an appropriate flag, or specify a strict set of expected types before the try-except block:
Activity
JelleZijlstra commentedon May 1, 2020
You can work around this by adding an explicit annotation of
Tuple[str, ...]. I guess mypy could implicitly infer such a type for code like the above, but that runs into issues like #1026.vpogrebi commentedon May 1, 2020
@JelleZijlstra
Tested your suggestion, but that does not work:
... results in
JelleZijlstra commentedon May 1, 2020
You should annotate only the first definition.
vpogrebi commentedon May 1, 2020
Tried that, too - which brings back to the initial error:
Error:
hauntsaninja commentedon May 1, 2020
You should annotate it (once) as
Tuple[str, ...](with literal..., just copy and paste). This is the type for a tuple whose elements are allstr, but could be of variable length (https://mypy.readthedocs.io/en/stable/kinds_of_types.html#tuple-types).vpogrebi commentedon May 1, 2020
Thank you, that worked. I had my own solution that involved Union, but I like this one better (I was not aware of the ... type annotation).
But still - it is desired to have these mypy errors eliminated in the future releases.
DevilXD commentedon May 2, 2020
@vpogrebi This is not a mypy bug, the tuple infers the first type it encounters when assigned to, and assigning a different type (with different amount of items inside the tuple) later on is an error - this is valid behavior. You need to explicitly tell it to either accept a variable amount of items via
Tuple[str, ...], allow redefinition via an appropriate flag, or specify a strict set of expected types before the try-except block:AlexWaygood commentedon Mar 25, 2022
I agree with @DevilXD that this doesn't really seem like a bug.