Skip to content
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

Better story for import redefinitions #13969

Merged
merged 2 commits into from
Nov 3, 2022

Conversation

hauntsaninja
Copy link
Collaborator

@hauntsaninja hauntsaninja commented Oct 31, 2022

This changes our importing logic to be more consistent and to treat import statements more like assignments.

Fixes #13803, fixes #13914, fixes half of #12965, probably fixes #12574

The primary motivation for this is when typing modules as protocols, as in #13803. But it turns out we already allowed redefinition with "from" imports, so this also seems like a nice consistency win.

We move shared logic from visit_import_all and visit_import_from (via process_imported_symbol) into add_imported_symbol. We then reuse it in visit_import.

To simplify stuff, we inline the code from add_module_symbol into visit_import. Then we copy over logic from add_symbol, because MypyFile is not a SymbolTableNode, but this isn't the worst thing ever.

Finally, we now need to check non-from import statements like assignments, which was a thing we weren't doing earlier.

This changes our importing logic to be more consistent and to treat
import statements more like assignments.

Fixes python#13803

The primary motivation for this is when typing modules as protocols, as
in the linked issue. But it turns out we already allowed redefinition
with from imports, so this just seems like a nice consistency win.

We move shared logic from visit_import_all and visit_import_from (via
process_imported_symbol) into add_imported_symbol. We then reuse it in
visit_import.

To simplify stuff, we inline the code from add_module_symbol into
visit_import. Then we copy over logic from add_symbol, because MypyFile
is not a SymbolTableNode, but this isn't the worst thing ever.

Finally, we now need to check non-from import statements like
assignments, which was a thing we weren't doing earlier.
[stale]
[out2]
tmp/b.py:4: error: Name "a" already defined on line 3
[stale b]
Copy link
Collaborator Author

@hauntsaninja hauntsaninja Oct 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not fully sure what's going on with this particular test case, maybe we should delete it since the behaviour now looks pretty similar to ignore. Alternatively, could add some new special case logic in checker.py to disallow assignments via import x to things typed Any (although I don't really like the idea of doing that).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep this test case, though it's not super interesting. The changes to the test case look reasonable to me. There's no particular reason to generate an error here.

@github-actions

This comment has been minimized.

@hauntsaninja
Copy link
Collaborator Author

Okay, primer looks pretty good. The one change is some type ignores go from error code no-redef to assignment. I think this is okay — it's more consistent with what would happen with "from" imports.

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks more consistent that the pretty ad-hoc rules we had for imports previously. Left some ideas about additional test cases. If you don't think they are useful, this is ready to merge.

[stale]
[out2]
tmp/b.py:4: error: Name "a" already defined on line 3
[stale b]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep this test case, though it's not super interesting. The changes to the test case look reasonable to me. There's no particular reason to generate an error here.

def f(self) -> str: ...

cond: bool
t: P
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like c: Type[Cls] and then conditionally importing two different classes? Also, f: Callable[[int], str] and then importing functions, perhaps. Or maybe these are covered by existing test cases?

@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2022

Diff from mypy_primer, showing the effect of this PR on open source code:

psycopg (https://github.com/psycopg/psycopg)
+ psycopg/psycopg/pq/__init__.py:89: error: Unused "type: ignore" comment
+ psycopg/psycopg/pq/__init__.py:89: error: Incompatible import of "module" (imported name has type Module, local name has type "object")  [assignment]
+ psycopg/psycopg/pq/__init__.py:89: note: Error code "assignment" not covered by "type: ignore" comment
+ tests/test_copy.py:312: error: Unused "type: ignore" comment
+ tests/test_copy.py:312: error: Incompatible import of "BaseDumper" (imported name has type "Type[StrBinaryDumper]", local name has type "Type[StrDumper]")  [assignment]
+ tests/test_copy.py:312: note: Error code "assignment" not covered by "type: ignore" comment
+ tests/test_copy_async.py:305: error: Unused "type: ignore" comment
+ tests/test_copy_async.py:305: error: Incompatible import of "BaseDumper" (imported name has type "Type[StrBinaryDumper]", local name has type "Type[StrDumper]")  [assignment]
+ tests/test_copy_async.py:305: note: Error code "assignment" not covered by "type: ignore" comment

cwltool (https://github.com/common-workflow-language/cwltool)
+ cwltool/utils.py:252: error: Unused "type: ignore" comment
+ cwltool/utils.py:254: error: Unused "type: ignore" comment

werkzeug (https://github.com/pallets/werkzeug)
+ src/werkzeug/utils.py:267: error: Unused "type: ignore" comment

dragonchain (https://github.com/dragonchain/dragonchain)
+ dragonchain/transaction_processor/transaction_processor.py:45:9: error: Name "processor" already defined (by an import)  [no-redef]
+ dragonchain/transaction_processor/transaction_processor.py:47:9: error: Name "processor" already defined (by an import)  [no-redef]
+ dragonchain/transaction_processor/transaction_processor.py:49:9: error: Name "processor" already defined (by an import)  [no-redef]
+ dragonchain/transaction_processor/transaction_processor.py:52:9: error: Name "processor" already defined (by an import)  [no-redef]
+ dragonchain/transaction_processor/transaction_processor.py:54:9: error: Module has no attribute "setup"  [attr-defined]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:2695: error: Unused "type: ignore" comment
+ pandas/core/frame.py:2695: error: Incompatible import of "statawriter" (imported name has type "Type[StataWriter117]", local name has type "Type[StataWriter]")  [assignment]
+ pandas/core/frame.py:2695: note: Error code "assignment" not covered by "type: ignore" comment
+ pandas/core/frame.py:2700: error: Unused "type: ignore" comment
+ pandas/core/frame.py:2700: error: Incompatible import of "statawriter" (imported name has type "Type[StataWriterUTF8]", local name has type "Type[StataWriter]")  [assignment]
+ pandas/core/frame.py:2700: note: Error code "assignment" not covered by "type: ignore" comment

pytest (https://github.com/pytest-dev/pytest)
- testing/_py/test_local.py:1156: error: Name "isimportable" already defined (possibly by an import)  [no-redef]

jinja (https://github.com/pallets/jinja)
+ src/jinja2/utils.py:185: error: Unused "type: ignore" comment

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/client_reqrep.py:75: error: Unused "type: ignore" comment

@hauntsaninja hauntsaninja merged commit a4da89e into python:master Nov 3, 2022
@hauntsaninja hauntsaninja deleted the import-redef branch November 3, 2022 05:10
wxtim added a commit to wxtim/cylc that referenced this pull request Feb 7, 2023
datamel added a commit to cylc/cylc-flow that referenced this pull request Feb 7, 2023
wxtim added a commit to wxtim/cylc that referenced this pull request Feb 17, 2023
…lc into fix_localhost_platform_matching

* 'fix_localhost_platform_matching' of github.com:wxtim/cylc:
  Fix a bug preventing `cylc vip --workflow-name=foo` from working. (cylc#5349)
  fix no rose vars in cylc view (cylc#5367)
  Cylc lint fixes (cylc#5363)
  data store: support unsatisfied ext_trigger
  fix mypy fail caused by python/mypy#13969
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants