Skip to content

Running dataclass transform in a later pass to fix crashes #12762

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 16 commits into from
May 11, 2022

Conversation

JukkaL
Copy link
Collaborator

@JukkaL JukkaL commented May 10, 2022

The dataclass plugin could crash if it encountered a placeholder. Fix the issue by
running the plugin after the main semantic analysis pass, when all placeholders have
been resolved.

Also add a new hook called get_class_decorator_hook_2 that is used by the
dataclass plugin.

We may want to do a similar change to the attrs plugin, but let's change one thing
at a time.

Fix #12685.

@github-actions

This comment has been minimized.

mypy/plugin.py Outdated
@@ -692,9 +692,32 @@ def get_class_decorator_hook(self, fullname: str

The plugin can modify a TypeInfo _in place_ (for example add some generated
methods to the symbol table). This hook is called after the class body was
semantically analyzed.
semantically analyzed, but *there may still be placeholders*.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe briefly mention that placeholders are caused by forward refs (plugin devs read this file as docs).

@@ -390,6 +397,9 @@ def collect_attributes(self) -> Optional[List[DataclassAttribute]]:
# we'll have unmodified attrs laying around.
all_attrs = attrs.copy()
for info in cls.info.mro[1:-1]:
if 'dataclass_tag' in info.metadata and 'dataclass' not in info.metadata:
# We haven't processed the base class yet. Need another pass.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe also add the meaning of returning None to the docstring?

# If we encounter a base class that has not been processed, we'll run another
# pass. This should eventually reach a fixed point.
while incomplete:
assert num_passes < 5, "Internal error: too many class plugin hook passes"
Copy link
Member

Choose a reason for hiding this comment

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

This looks a bit arbitrary. I would say we need a large number, so this will not happen in legitimate cases.

assert tree
for _, node, _ in tree.local_definitions():
if isinstance(node.node, TypeInfo):
saved = (module, node.node, None) # module, class, function
with errors.scope.saved_scope(saved) if errors.scope else nullcontext():
with state.manager.semantic_analyzer.file_context(tree, state.options, node.node):
Copy link
Member

Choose a reason for hiding this comment

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

Not sure why these changes are needed here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Some errors were reported incorrectly in test cases (in the wrong file etc.) without these changes. I think that that this previously implicitly assumed that the context state was set up via some earlier pass, and the new pass invalidated some of the assumptions. Now we explicitly set the state to what we require.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@JukkaL JukkaL merged commit 03901ef into master May 11, 2022
@JukkaL JukkaL deleted the fix-generic-dataclass-crash branch May 11, 2022 12:38
JukkaL added a commit that referenced this pull request May 12, 2022
This is similar to #12762, but for attrs classes.
JukkaL added a commit that referenced this pull request May 13, 2022
Move the attrs plugin to a later pass, so that we won't have placeholders. Fix
various issues related to forward references and generic inheritance, including
some crashes.

This is follow-up to #12762 and related to #12656 and #12633.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash involving dataclasses, generics, forward references
2 participants