Repository navigation
mypy bug with try/except conditional imports #1153
Description
Activity
Pretty sure this is a dup, but I can't find the issue.
Related to #649.
Note that #649 was closed; a buch of "leftover" bugs were opened in its
place, but I don't see one that matches this pattern, so I think it's a new
case.On Mon, Jan 25, 2016 at 3:19 PM, Ryan Gonzalez notifications@github.com
wrote:—
Reply to this email directly or view it on GitHub
#1153 (comment).--Guido van Rossum (python.org/~guido)
Closed by mistake.
Another example from #2251 (reported by @RitwikGupta):
try: # Python 3 from urllib.request import urlopen except ImportError: # Python 2 from urllib2 import urlopen
Reacted by Shivani Bhardwaj, Keith Smiley, Islam Mesha, Nico Schlömer and Joel NiemeläAnd another from #2253:
This python code generates an error. It's a common idiom and it would be good if mypy could check for it in some way.
try: import cPickle as pickle except ImportError: import pickle
$ mypy --py2 --silent-imports bad.py bad.py:4: error: Name 'pickle' already definedReacted by Islam MeshaThe current workaround is to add a
# type: ignorecomment. For example:try: import cPickle as pickle except ImportError: import pickle # type: ignore # <<-- add this
Reacted by Tuukka Mustonen, Antti Kaihola, Islam Mesha, Mohamed Eldesouki, Redouane Kachach and Yi-Han ChenFYI, this doesn't appear to work with sub-modules:
# This will error try: import foo.bar except ImportError: foo = None # type:ignore
This seems to work though:
# This will pass try: import doesnt.exist # type:ignore except ImportError: doesnt = None # So will this try: import collections.abc # type:ignore except ImportError: collections = None assert doesnt is None assert collections is not None
This is particularly difficult when the import that's happening is a
typingimport.For example, this works:
$ mypy --version mypy 0.530 $ cat no_try.py from typing import Dict, Any JSON = Dict[str, Any] def accept(obj: JSON) -> Any: return obj.pop('hello') $ mypy --ignore-missing-imports no_try.py
$ cat with_try.py try: from typing import Dict, Any except: from backports.typing import Dict, Any # type: ignore JSON = Dict[str, Any] def accept(obj: JSON) -> Any: return obj.pop('hello') $ mypy --ignore-missing-imports with_try.py with_try.py:10: error: Invalid type "with_try.JSON" with_try.py:11: error: JSON? has no attribute "pop"This program should typecheck.
45 remaining items
- added a commit that references this issue
on Jun 9, 2021 A pattern that might be nicer for some?
if TYPE_CHECKING or sys.version_info < (3, 8, 0): from typing_extensions import Literal else: from typing import Literal
Reacted by Dev Chakraborty, Jeffrey C. Lerman, lovetheguitar, Jasha Sommer-Simpson and Ellen Agarwal- added a commit that references this issue
on Jan 14, 2022 Building on an answer from @cjerdonek, would this be an acceptable workaround instead of
# type: ignore?:try: from py3_pkg import module as _module except: from py2_pkg import module else: module = _module
- added a commit that references this issue
on Aug 5, 2022 Is this going to be fixed anytime soon?
Reacted by Joel NiemeläNo, it's not, and it's not clear that it should.
A majority of cases I've seen here are to work around Python stdlib changes, especially Python 2 to Python 3 stuff.
sys.version_infochecks are the preferred way to do this. Also Python 2 is dead.if sys.version_info >= (3, 8): import importlib.metadata as importlib_metadata else: import importlib_metadataFor the remaining cases, it's often not clear that it's sound, especially given nominal typing. Even if the API is structurally the same, nominal
isinstancechecks could result in surprising behaviour from mypy.The only thing we should do in this space is #5018 where you can explicitly define exactly the structure you want with a Protocol, and mypy will confirm.
For all other cases, if you want to lie to the typechecker, please, go ahead and lie to the type checker (or type ignore):
if TYPE_CHECKING: import json else: try: import simplejson as json except ImportError: import jsonReacted by Eric Traut, James McKinney, Thomas M Kehrenberg, Jonathon Reinhart, Dmitriy Stepanov and 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко)Reacted by Ari Entlich, Craig Rodrigues, Wim Jeantine-Glenn, Minglei Li, Sean Humes, Jason Yamada-Hanff and Joel NiemeläReacted by 依云 and Joel NiemeläFYI "type ignore" doesn't work well because in some cases it will cause
Unused "type: ignore" commenterrors elsewhere (e.g. GitHub Actions).Reacted by Seppo Enarvi
resulst in the error
error: Name 'simplejson' already defined