Skip to content

fix(11064): fix crash due to undefined cyclic import * #11346

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

hi-ogawa
Copy link
Contributor

@hi-ogawa hi-ogawa commented Oct 17, 2021

(Sorry for another draft PR. I wanted to see CI's results. I'll soon write a detail below)
Sorry for stalling this PR so long. I updated the description below.

Description

Fixes #11064

It seems that the original issue has been fixed already (which corresponds to the test case testCyclicUndefinedImportWithStar3). However, the other two cases (testCyclicUndefinedImportWithStar1 and testCyclicUndefinedImportWithStar2) still cause crash, so this PR is indended to fix them.
While working on the fix, first I tried to detect cyclic import during semanal (e.g. from add_imported_symbol), but in the end, it turns out simply setting can_defer produces sensible error message, so that's what this PR does.

Test Plan

I added four tests related to cyclic import in check-modules.test:

  • testCyclicUndefinedImportWithName
  • testCyclicUndefinedImportWithStar1
  • testCyclicUndefinedImportWithStar2
  • testCyclicUndefinedImportWithStar3 (replication of the linked issue)

where testCyclicUndefinedImportWithName and testCyclicUndefinedImportWithStar3 are already working in current master, and the other two are addressed in this PR.

@hi-ogawa hi-ogawa force-pushed the 11064-fix-cyclic-import-star-defer-crash branch from e4ff209 to 17268de Compare November 13, 2021 10:41
@hi-ogawa hi-ogawa marked this pull request as ready for review November 14, 2021 01:22
Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

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

Thanks for the PR and the additional test cases!

First off, note that I don't understand the deferral parts of the semantic analyser very well :-) Because of my lack of familiarity, while it's clear to me how this avoids the assertion, it's hard for me to know whether this change is actually correct. For example, should we be changing this in add_symbol_table_node itself, rather than just this one place?

Reading the code with that line of thinking got me this alternative patch:

diff --git a/mypy/semanal.py b/mypy/semanal.py
index 3c0d548b2..dc70d0918 100644
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -4567,7 +4567,12 @@ class SemanticAnalyzer(NodeVisitor[None],
         names = self.current_symbol_table(escape_comprehensions=escape_comprehensions)
         existing = names.get(name)
         if isinstance(symbol.node, PlaceholderNode) and can_defer:
-            self.defer(context)
+            if context is not None:
+                self.process_placeholder(name, 'name', context)
+            else:
+                # see note in docstring about None contexts
+                self.defer(context)
+
         if (existing is not None
                 and context is not None
                 and not is_valid_replacement(existing, symbol)):

Reading the docstrings of defer and process_placeholder, I feel pretty good about that. The net effect should be pretty similar to your PR, but perhaps less specific to the exact issue in #11064 and ensures we'll get some kind of error message if we do hit that during the final iteration. It also avoids crashes in the test cases you added.

What do you think? :-)

@hi-ogawa
Copy link
Contributor Author

hi-ogawa commented Nov 14, 2021

Thanks for the suggestion!
To tell you the truth, I really don't have a clue about defer/placeholder mechanism.
My strategy for investigating this issue was to first try to understand why the case testCyclicUndefinedImportWithName is handled properly (i.e. visit_import_from) and to apply the same solution to the case of "star" import (i.e. visit_import_all), but from what I tried, the situation doesn't seem to be so simple and I ended up just adding can_defer.
My instinct was that a fix should be possible before going to add_simbol_table_node and so I was a bit hesitant to change things around the code you mention (in fact, I haven't even read those parts yet).
I really appreciate the discussion with you, but I have to admit that I might not be up to this task yet.

@jrabbit
Copy link

jrabbit commented Nov 15, 2021

What's the changed behavior supposed to be for large codebases w/ some circular imports? Because I still get a deferral trace and the same message about checking being halted for errors. (when running mypy w/ this PR)

@hauntsaninja
Copy link
Collaborator

@jrabbit it sounds like you have a different issue than the one in #11064. Do you have a stack trace, and ideally a repro you can share?

@jrabbit
Copy link

jrabbit commented Nov 16, 2021

Ah, Yeah I can collect logs, I don't know specifically what's causing it, it's a massive somewhat old (and unfortunately, closed source) codebase. I can look into it some more.

@hauntsaninja
Copy link
Collaborator

I really appreciate the discussion with you, but I have to admit that I might not be up to this task yet.

I opened #11681 that builds on your work but uses that^ suggested diff. Thank you for making mypy better!!

@hi-ogawa hi-ogawa deleted the 11064-fix-cyclic-import-star-defer-crash branch December 9, 2021 03:51
@hi-ogawa
Copy link
Contributor Author

hi-ogawa commented Dec 9, 2021

@hauntsaninja Thanks for picking up my commits. I hope your PR will get merged soon!

JukkaL pushed a commit that referenced this pull request Dec 13, 2021
Fixes #11064. Co-authored by @hi-ogawa 

Pushes #11346 over the finish line. Implements the suggestion in 
#11346 (review)

Co-authored-by: Hiroshi Ogawa <[email protected]>
Co-authored-by: hauntsaninja <>
tushar-deepsource pushed a commit to DeepSourceCorp/mypy that referenced this pull request Jan 20, 2022
Fixes python#11064. Co-authored by @hi-ogawa 

Pushes python#11346 over the finish line. Implements the suggestion in 
python#11346 (review)

Co-authored-by: Hiroshi Ogawa <[email protected]>
Co-authored-by: hauntsaninja <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Semantic analysis deferral crash
3 participants