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

Fix crash overriding partial-type attribute with method #12943

Merged
merged 1 commit into from Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion mypy/checker.py
Expand Up @@ -1575,7 +1575,9 @@ def check_method_override_for_base_with_name(
# it can be checked for compatibility.
original_type = get_proper_type(base_attr.type)
original_node = base_attr.node
if original_type is None:
# `original_type` can be partial if (e.g.) it is originally an
# instance variable from an `__init__` block that becomes deferred.
if original_type is None or isinstance(original_type, PartialType):
if self.pass_num < self.last_pass:
# If there are passes left, defer this node until next pass,
# otherwise try reconstructing the method type from available information.
Expand Down
18 changes: 18 additions & 0 deletions test-data/unit/check-classes.test
Expand Up @@ -151,6 +151,24 @@ class Derived(Base):
__hash__ = 1 # E: Incompatible types in assignment (expression has type "int", base class "Base" defined the type as "Callable[[Base], int]")


[case testOverridePartialAttributeWithMethod]
# This was crashing: https://github.com/python/mypy/issues/11686.
class Base:
def __init__(self, arg: int):
self.partial_type = [] # E: Need type annotation for "partial_type" (hint: "partial_type: List[<type>] = ...")
self.force_deferral = []

# Force inference of the `force_deferral` attribute in `__init__` to be
# deferred to a later pass by providing a definition in another context,
# which means `partial_type` remains only partially inferred.
force_deferral = [] # E: Need type annotation for "force_deferral" (hint: "force_deferral: List[<type>] = ...")


class Derived(Base):
def partial_type(self) -> int: # E: Signature of "partial_type" incompatible with supertype "Base"
...


-- Attributes
-- ----------

Expand Down