-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Remove ModuleType.__getattr__ #6357
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
Conversation
This caused false negatives for mypy -- mypy would consider that any module would have any attribute. The method also does not exist at runtime. I've also updated `builtins.__import__`, `importlib.__import__`, and `importlib.import_module` to return `Any`. I don't have a strong opinion on this change, but this arguably minimizes the impact of the removal, and maintains the return types of these functions consistent. Also, it could be argued that since arbitrary objects can be stuffed into `sys.modules` (and I've heard people actually suggest taking advantage of this), the `Any` type best reflects this. There may be other reasonable ways to deal with module objects, but I think that adding `ModuleType.__getattr__` regresses things too much.
Diff from mypy_primer, showing the effect of this PR on open source code: pylint (https://github.com/pycqa/pylint.git)
- pylint/checkers/utils.py:326: error: unused "type: ignore" comment
- pylint/checkers/utils.py:326: error: Module has no attribute "__iter__" (not iterable) [attr-defined]
isort (https://github.com/pycqa/isort.git)
- isort/_future/__init__.py:9: error: unused "type: ignore" comment
- isort/_future/__init__.py:10: error: unused "type: ignore" comment
- isort/output.py:504: error: unused "type: ignore" comment
- isort/output.py:516: error: unused "type: ignore" comment
- isort/output.py:523: error: unused "type: ignore" comment
pip (https://github.com/pypa/pip.git)
- src/pip/_internal/locations/__init__.py:58: error: unused "type: ignore" comment
- src/pip/_internal/network/session.py:106: error: unused "type: ignore" comment
sphinx (https://github.com/sphinx-doc/sphinx.git)
- sphinx/util/typing.py:228: error: unused "type: ignore" comment
- sphinx/util/typing.py:428: error: unused "type: ignore" comment
- sphinx/util/inspect.py:433: error: unused "type: ignore" comment
- sphinx/util/inspect.py:436: error: unused "type: ignore" comment
- sphinx/util/inspect.py:439: error: unused "type: ignore" comment
- sphinx/util/docutils.py:52: error: unused "type: ignore" comment
- sphinx/util/docutils.py:53: error: unused "type: ignore" comment
- sphinx/util/docutils.py:67: error: unused "type: ignore" comment
- sphinx/util/docutils.py:81: error: unused "type: ignore" comment
- sphinx/util/docutils.py:95: error: unused "type: ignore" comment
- sphinx/util/docutils.py:110: error: unused "type: ignore" comment
- sphinx/domains/python.py:1452: error: unused "type: ignore" comment
- sphinx/writers/manpage.py:110: error: unused "type: ignore" comment
- sphinx/testing/util.py:126: error: unused "type: ignore" comment
- sphinx/testing/util.py:127: error: unused "type: ignore" comment
+ sphinx/ext/napoleon/__init__.py:467: error: unused "type: ignore" comment
- sphinx/util/compat.py:29: error: unused "type: ignore" comment
graphql-core (https://github.com/graphql-python/graphql-core.git)
+ tests/pyutils/test_inspect.py:24: error: unused "type: ignore" comment
+ tests/pyutils/test_inspect.py:28: error: unused "type: ignore" comment
+ tests/pyutils/test_inspect.py:33: error: unused "type: ignore" comment
+ tests/pyutils/test_inspect.py:37: error: unused "type: ignore" comment
+ tests/pyutils/test_inspect.py:42: error: unused "type: ignore" comment
+ tests/pyutils/test_inspect.py:46: error: unused "type: ignore" comment
kornia (https://github.com/kornia/kornia.git)
+ kornia/testing/__init__.py:16: error: Module has no attribute "util" [attr-defined]
python-chess (https://github.com/niklasf/python-chess.git)
- chess/engine.py:122: error: unused "type: ignore" comment
- chess/engine.py:123: error: unused "type: ignore" comment
- chess/engine.py:1209: error: unused "type: ignore" comment
core (https://github.com/home-assistant/core.git)
- homeassistant/components/http/forwarded.py:91: error: unused "type: ignore" comment
- homeassistant/auth/mfa_modules/__init__.py:136: error: unused "type: ignore" comment
- homeassistant/auth/providers/__init__.py:145: error: unused "type: ignore" comment
- homeassistant/config.py:648: error: unused "type: ignore" comment
- homeassistant/config.py:651: error: unused "type: ignore" comment
- homeassistant/config.py:662: error: unused "type: ignore" comment
- homeassistant/config.py:672: error: unused "type: ignore" comment
- homeassistant/config.py:673: error: unused "type: ignore" comment
- homeassistant/config.py:753: error: unused "type: ignore" comment
- homeassistant/config.py:895: error: unused "type: ignore" comment
- homeassistant/setup.py:241: error: unused "type: ignore" comment
- homeassistant/setup.py:246: error: unused "type: ignore" comment
- homeassistant/helpers/check_config.py:161: error: unused "type: ignore" comment
- homeassistant/config_entries.py:310: error: unused "type: ignore" comment
- homeassistant/config_entries.py:449: error: unused "type: ignore" comment
- homeassistant/config_entries.py:488: error: unused "type: ignore" comment
- homeassistant/config_entries.py:525: error: unused "type: ignore" comment
- homeassistant/helpers/condition.py:929: error: unused "type: ignore" comment
- homeassistant/helpers/condition.py:977: error: unused "type: ignore" comment
- homeassistant/helpers/script.py:260: error: unused "type: ignore" comment
- homeassistant/helpers/script.py:262: error: unused "type: ignore" comment
- homeassistant/helpers/script.py:269: error: unused "type: ignore" comment
- homeassistant/helpers/reload.py:81: error: unused "type: ignore" comment
- homeassistant/helpers/reload.py:82: error: unused "type: ignore" comment
- homeassistant/components/device_tracker/legacy.py:241: error: unused "type: ignore" comment
- homeassistant/components/device_tracker/legacy.py:246: error: unused "type: ignore" comment
- homeassistant/components/device_tracker/legacy.py:251: error: unused "type: ignore" comment
- homeassistant/components/device_tracker/legacy.py:256: error: unused "type: ignore" comment
- homeassistant/components/notify/legacy.py:61: error: unused "type: ignore" comment
- homeassistant/components/notify/legacy.py:66: error: unused "type: ignore" comment
streamlit (https://github.com/streamlit/streamlit.git)
- lib/streamlit/script_runner.py:432: error: unused "type: ignore" comment
- lib/streamlit/script_runner.py:439: error: unused "type: ignore" comment
aiohttp (https://github.com/aio-libs/aiohttp.git)
- aiohttp/connector.py:1306: error: unused "type: ignore" comment
- aiohttp/web_runner.py:181: error: unused "type: ignore" comment
- aiohttp/pytest_plugin.py:244: error: unused "type: ignore" comment
edgedb (https://github.com/edgedb/edgedb.git)
- edb/server/pgconnparams.py:75: error: unused "type: ignore" comment
werkzeug (https://github.com/pallets/werkzeug.git)
- src/werkzeug/_reloader.py:20: error: unused "type: ignore" comment
+ tests/test_wrappers.py:856: error: Function is missing a return type annotation
|
(As the person who introduced this change), I don't have a strong opinion on what the return type of |
Could mypy instead be changed so that if an object is a specific, known module, it ignores the |
A slightly more "out there" suggestion, but —something else I was wondering about a few weeks ago, when we discussed this last, was whether type-checkers could be special-cased to recognise that the return type of (1) import collections as c
reveal_type(c.deque()) # Revealed type is "collections.deque[<nothing>]" (2) c = __import__("collections")
reveal_type(c.deque()) # Revealed type is "Any" But I appreciate that this probably isn't the right place to discuss the feasibility of that idea. |
I imagine most cases where people call these functions the argument is going to be dynamic. |
No, you're right. I thought I remembered there being more instances in the diff here where people were just |
I'll have a look. If this is straightforward to implement, I'll abandon this PR. |
python/typeshd#6302 added `__getattr__`, but we don't want to always use it, as it can result in undefined references to module attributes being undetected. This is an alternative to python/typeshed#6357. Tested manually with a recent typeshed.
python/typeshd#6302 added `__getattr__`, but we don't want to always use it, as it can result in undefined references to module attributes being undetected. This is an alternative to python/typeshed#6357. Tested manually with a recent typeshed.
The issue was actually very simple to work around in mypy, so this PR is no longer needed (python/mypy#11597). |
) python/typeshd#6302 added `__getattr__`, but we don't want to always use it, as it can result in undefined references to module attributes being undetected. This is an alternative to python/typeshed#6357. Tested manually with a recent typeshed.
This caused false negatives for mypy -- mypy would consider that any
module would have any attribute. The method also does not exist at
runtime.
I've also updated
builtins.__import__
,importlib.__import__
, andimportlib.import_module
to returnAny
. I don't have a strongopinion on this change, but this arguably minimizes the impact of the
removal, and maintains the return types of these functions consistent.
Also, it could be argued that since arbitrary objects can be stuffed
into
sys.modules
(and I've heard people actually suggest takingadvantage of this), the
Any
type best reflects this.There may be other reasonable ways to deal with module objects, but I
think that adding
ModuleType.__getattr__
regresses things too much.