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 slots and deleted attributes in incremental mode #12645

Merged
merged 1 commit into from Apr 21, 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: 4 additions & 0 deletions mypy/nodes.py
Expand Up @@ -2907,6 +2907,8 @@ def serialize(self) -> JsonDict:
None if self.typeddict_type is None else self.typeddict_type.serialize(),
'flags': get_flags(self, TypeInfo.FLAGS),
'metadata': self.metadata,
'slots': list(sorted(self.slots)) if self.slots is not None else None,
'deletable_attributes': self.deletable_attributes,
}
return data

Expand Down Expand Up @@ -2944,6 +2946,8 @@ def deserialize(cls, data: JsonDict) -> 'TypeInfo':
ti.typeddict_type = (None if data['typeddict_type'] is None
else mypy.types.TypedDictType.deserialize(data['typeddict_type']))
ti.metadata = data['metadata']
ti.slots = set(data['slots']) if data['slots'] is not None else None
ti.deletable_attributes = data['deletable_attributes']
set_flags(ti, data['flags'])
return ti

Expand Down
2 changes: 2 additions & 0 deletions mypyc/ir/class_ir.py
Expand Up @@ -325,6 +325,7 @@ def serialize(self) -> JsonDict:
'children': [
cir.fullname for cir in self.children
] if self.children is not None else None,
'deletable': self.deletable,
}

@classmethod
Expand Down Expand Up @@ -373,6 +374,7 @@ def deserialize(cls, data: JsonDict, ctx: 'DeserMaps') -> 'ClassIR':
ir.mro = [ctx.classes[s] for s in data['mro']]
ir.base_mro = [ctx.classes[s] for s in data['base_mro']]
ir.children = data['children'] and [ctx.classes[s] for s in data['children']]
ir.deletable = data['deletable']

return ir

Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/fixtures/ir.py
Expand Up @@ -294,7 +294,7 @@ def next(i: Iterator[T]) -> T: pass
def next(i: Iterator[T], default: T) -> T: pass
def hash(o: object) -> int: ...
def globals() -> Dict[str, Any]: ...
def getattr(obj: object, name: str) -> Any: ...
def getattr(obj: object, name: str, default: Any = None) -> Any: ...
def setattr(obj: object, name: str, value: Any) -> None: ...
def enumerate(x: Iterable[T]) -> Iterator[Tuple[int, T]]: ...
@overload
Expand Down
22 changes: 22 additions & 0 deletions mypyc/test-data/run-multimodule.test
Expand Up @@ -798,3 +798,25 @@ def foo() -> int: return 10
import native

[rechecked native, other_a]

[case testIncrementalCompilationWithDeletable]
import other_a
[file other_a.py]
from other_b import C
[file other_a.py.2]
from other_b import C
c = C()
print(getattr(c, 'x', None))
del c.x
print(getattr(c, 'x', None))
[file other_b.py]
class C:
__deletable__ = ['x']
def __init__(self) -> None:
self.x = 0
[file driver.py]
import native
[out]
[out2]
0
None
25 changes: 25 additions & 0 deletions test-data/unit/check-incremental.test
Expand Up @@ -5633,3 +5633,28 @@ main:5: error: Cannot override final attribute "x" (previously declared in base
main:3: error: Cannot override writable attribute "x" with a final one
main:4: error: Cannot extend enum with existing members: "FinalEnum"
main:5: error: Cannot override final attribute "x" (previously declared in base class "FinalEnum")

[case testSlotsSerialization]
import a
[file a.py]
from b import C

class D(C):
pass
[file b.py]
class C:
__slots__ = ('x',)
[file a.py.2]
from b import C

class D(C):
__slots__ = ('y',)

def __init__(self) -> None:
self.x = 1
self.y = 2
self.z = 3
[builtins fixtures/tuple.pyi]
[out]
[out2]
tmp/a.py:9: error: Trying to assign name "z" that is not in "__slots__" of type "a.D"