Skip to content

Commit 8ab7aa2

Browse files
authored
type.__dict__ (#5957)
1 parent 16aaad7 commit 8ab7aa2

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

extra_tests/snippets/builtin_type.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,3 +595,15 @@ def my_repr_func():
595595

596596
# https://github.com/RustPython/RustPython/issues/3100
597597
assert issubclass(types.BuiltinMethodType, types.BuiltinFunctionType)
598+
599+
assert type.__dict__["__dict__"].__objclass__ is type
600+
assert (
601+
type(type(type.__dict__["__dict__"]).__objclass__).__name__ == "member_descriptor"
602+
)
603+
604+
605+
class A(type):
606+
pass
607+
608+
609+
assert "__dict__" not in A.__dict__

vm/src/builtins/type.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -936,9 +936,9 @@ impl Constructor for PyType {
936936
return Err(vm.new_value_error("type name must not contain null characters"));
937937
}
938938

939-
let (metatype, base, bases) = if bases.is_empty() {
939+
let (metatype, base, bases, base_is_type) = if bases.is_empty() {
940940
let base = vm.ctx.types.object_type.to_owned();
941-
(metatype, base.clone(), vec![base])
941+
(metatype, base.clone(), vec![base], false)
942942
} else {
943943
let bases = bases
944944
.iter()
@@ -972,8 +972,9 @@ impl Constructor for PyType {
972972
};
973973

974974
let base = best_base(&bases, vm)?;
975+
let base_is_type = base.is(vm.ctx.types.type_type);
975976

976-
(metatype, base.to_owned(), bases)
977+
(metatype, base.to_owned(), bases, base_is_type)
977978
};
978979

979980
let qualname = dict
@@ -1021,17 +1022,21 @@ impl Constructor for PyType {
10211022
// All *classes* should have a dict. Exceptions are *instances* of
10221023
// classes that define __slots__ and instances of built-in classes
10231024
// (with exceptions, e.g function)
1024-
let __dict__ = identifier!(vm, __dict__);
1025-
attributes.entry(__dict__).or_insert_with(|| {
1026-
vm.ctx
1027-
.new_static_getset(
1028-
"__dict__",
1029-
vm.ctx.types.type_type,
1030-
subtype_get_dict,
1031-
subtype_set_dict,
1032-
)
1033-
.into()
1034-
});
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+
}
10351040

10361041
// TODO: Flags is currently initialized with HAS_DICT. Should be
10371042
// updated when __slots__ are supported (toggling the flag off if

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy