Skip to content

Commit d56cd41

Browse files
committed
Fix __dict__ getset type
1 parent c497061 commit d56cd41

File tree

2 files changed

+18
-25
lines changed

2 files changed

+18
-25
lines changed

Lib/test/test_typing.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,8 +2885,6 @@ def method(self) -> int: ...
28852885

28862886
self.assertNotIsSubclass(NotImpl, Foo)
28872887

2888-
# TODO: RUSTPYTHON
2889-
@unittest.expectedFailure
28902888
def test_pep695_generics_can_be_runtime_checkable(self):
28912889
@runtime_checkable
28922890
class HasX(Protocol):
@@ -3336,8 +3334,6 @@ class D(PNonCall): ...
33363334
with self.assertRaisesRegex(TypeError, non_callable_members_illegal):
33373335
issubclass(D, PNonCall)
33383336

3339-
# TODO: RUSTPYTHON
3340-
@unittest.expectedFailure
33413337
def test_no_weird_caching_with_issubclass_after_isinstance(self):
33423338
@runtime_checkable
33433339
class Spam(Protocol):
@@ -3404,8 +3400,6 @@ def __getattr__(self, attr):
34043400
):
34053401
issubclass(Eggs, Spam)
34063402

3407-
# TODO: RUSTPYTHON
3408-
@unittest.expectedFailure
34093403
def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self):
34103404
@runtime_checkable
34113405
class Spam[T](Protocol):

vm/src/builtins/type.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,25 +1019,6 @@ impl Constructor for PyType {
10191019
attributes.insert(identifier!(vm, __hash__), vm.ctx.none.clone().into());
10201020
}
10211021

1022-
// All *classes* should have a dict. Exceptions are *instances* of
1023-
// classes that define __slots__ and instances of built-in classes
1024-
// (with exceptions, e.g function)
1025-
// Also, type subclasses don't need their own __dict__ descriptor
1026-
// since they inherit it from type
1027-
if !base_is_type {
1028-
let __dict__ = identifier!(vm, __dict__);
1029-
attributes.entry(__dict__).or_insert_with(|| {
1030-
vm.ctx
1031-
.new_static_getset(
1032-
"__dict__",
1033-
vm.ctx.types.type_type,
1034-
subtype_get_dict,
1035-
subtype_set_dict,
1036-
)
1037-
.into()
1038-
});
1039-
}
1040-
10411022
let heaptype_slots: Option<PyRef<PyTuple<PyStrRef>>> =
10421023
if let Some(x) = attributes.get(identifier!(vm, __slots__)) {
10431024
let slots = if x.class().is(vm.ctx.types.str_type) {
@@ -1141,6 +1122,24 @@ impl Constructor for PyType {
11411122
cell.set(Some(typ.clone().into()));
11421123
};
11431124

1125+
// All *classes* should have a dict. Exceptions are *instances* of
1126+
// classes that define __slots__ and instances of built-in classes
1127+
// (with exceptions, e.g function)
1128+
// Also, type subclasses don't need their own __dict__ descriptor
1129+
// since they inherit it from type
1130+
1131+
// Add __dict__ descriptor after type creation to ensure correct __objclass__
1132+
if !base_is_type {
1133+
unsafe {
1134+
let descriptor =
1135+
vm.ctx
1136+
.new_getset("__dict__", &typ, subtype_get_dict, subtype_set_dict);
1137+
typ.attributes
1138+
.write()
1139+
.insert(identifier!(vm, __dict__), descriptor.into());
1140+
}
1141+
}
1142+
11441143
// avoid deadlock
11451144
let attributes = typ
11461145
.attributes

0 commit comments

Comments
 (0)