Skip to content

Commit c603d37

Browse files
Map RustPython type flags to CPython type flags
1 parent 85b2928 commit c603d37

File tree

2 files changed

+55
-45
lines changed

2 files changed

+55
-45
lines changed

crates/capi/src/object.rs

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,53 @@
1-
use core::ffi::c_ulong;
2-
31
use crate::PyObject;
2+
use core::ffi::c_ulong;
43
use rustpython_vm::builtins::PyType;
54
use rustpython_vm::{AsObject, Context, Py};
65
use std::sync::LazyLock;
76

87
pub struct PyTypeObject {
98
ty: LazyLock<&'static Py<PyType>>,
10-
flags: c_ulong,
119
}
1210

1311
impl PyTypeObject {
14-
const fn new(f: fn() -> &'static Py<PyType>, flags: c_ulong) -> PyTypeObject {
12+
const fn new(f: fn() -> &'static Py<PyType>) -> PyTypeObject {
1513
PyTypeObject {
1614
ty: LazyLock::new(f),
17-
flags,
1815
}
1916
}
2017
}
2118

22-
const PY_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0;
23-
const PY_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18;
24-
const PY_TPFLAGS_DEFAULT: c_ulong =
25-
PY_TPFLAGS_HAVE_STACKLESS_EXTENSION | PY_TPFLAGS_HAVE_VERSION_TAG;
26-
const PY_TPFLAGS_IMMUTABLETYPE: c_ulong = 1 << 8;
27-
const PY_TPFLAGS_BASETYPE: c_ulong = 1 << 10;
2819
const PY_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24;
20+
const PY_TPFLAGS_LIST_SUBCLASS: c_ulong = 1 << 25;
2921
const PY_TPFLAGS_TUPLE_SUBCLASS: c_ulong = 1 << 26;
22+
const PY_TPFLAGS_BYTES_SUBCLASS: c_ulong = 1 << 27;
3023
const PY_TPFLAGS_UNICODE_SUBCLASS: c_ulong = 1 << 28;
24+
const PY_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29;
25+
const PY_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30;
3126
const PY_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31;
3227

3328
#[unsafe(no_mangle)]
34-
pub static mut PyType_Type: PyTypeObject = PyTypeObject::new(
35-
|| {
36-
let zoo = &Context::genesis().types;
37-
zoo.type_type
38-
},
39-
PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_TYPE_SUBCLASS,
40-
);
29+
pub static mut PyType_Type: PyTypeObject = PyTypeObject::new(|| {
30+
let zoo = &Context::genesis().types;
31+
zoo.type_type
32+
});
4133

4234
#[unsafe(no_mangle)]
43-
pub static mut PyLong_Type: PyTypeObject = PyTypeObject::new(
44-
|| {
45-
let zoo = &Context::genesis().types;
46-
zoo.int_type
47-
},
48-
PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_LONG_SUBCLASS,
49-
);
35+
pub static mut PyLong_Type: PyTypeObject = PyTypeObject::new(|| {
36+
let zoo = &Context::genesis().types;
37+
zoo.int_type
38+
});
5039

5140
#[unsafe(no_mangle)]
52-
pub static mut PyTuple_Type: PyTypeObject = PyTypeObject::new(
53-
|| {
54-
let zoo = &Context::genesis().types;
55-
zoo.tuple_type
56-
},
57-
PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_TUPLE_SUBCLASS,
58-
);
41+
pub static mut PyTuple_Type: PyTypeObject = PyTypeObject::new(|| {
42+
let zoo = &Context::genesis().types;
43+
zoo.tuple_type
44+
});
5945

6046
#[unsafe(no_mangle)]
61-
pub static mut PyUnicode_Type: PyTypeObject = PyTypeObject::new(
62-
|| {
63-
let zoo = &Context::genesis().types;
64-
zoo.str_type
65-
},
66-
PY_TPFLAGS_DEFAULT
67-
| PY_TPFLAGS_IMMUTABLETYPE
68-
| PY_TPFLAGS_BASETYPE
69-
| PY_TPFLAGS_UNICODE_SUBCLASS,
70-
);
47+
pub static mut PyUnicode_Type: PyTypeObject = PyTypeObject::new(|| {
48+
let zoo = &Context::genesis().types;
49+
zoo.str_type
50+
});
7151

7252
#[unsafe(no_mangle)]
7353
pub extern "C" fn Py_TYPE(op: *mut PyObject) -> *mut PyTypeObject {
@@ -98,8 +78,38 @@ pub extern "C" fn PyType_GetFlags(ty: *mut PyTypeObject) -> c_ulong {
9878
panic!("PyType_GetFlags called with null type pointer");
9979
}
10080

101-
// SAFETY: caller guarantees this is a valid exported type object pointer.
102-
unsafe { (*ty).flags }
81+
let ctx =Context::genesis();
82+
let zoo = &ctx.types;
83+
let exp_zoo = &ctx.exceptions;
84+
let ty_inner = unsafe { *(*ty).ty };
85+
let mut flags = ty_inner.slots.flags.bits();
86+
87+
if ty_inner.is_subtype(zoo.int_type) {
88+
flags |= PY_TPFLAGS_LONG_SUBCLASS;
89+
}
90+
if ty_inner.is_subtype(zoo.list_type) {
91+
flags |= PY_TPFLAGS_LIST_SUBCLASS
92+
}
93+
if ty_inner.is_subtype(zoo.tuple_type) {
94+
flags |= PY_TPFLAGS_TUPLE_SUBCLASS;
95+
}
96+
if ty_inner.is_subtype(zoo.bytes_type) {
97+
flags |= PY_TPFLAGS_BYTES_SUBCLASS;
98+
}
99+
if ty_inner.is_subtype(zoo.str_type) {
100+
flags |= PY_TPFLAGS_UNICODE_SUBCLASS;
101+
}
102+
if ty_inner.is_subtype(zoo.dict_type) {
103+
flags |= PY_TPFLAGS_DICT_SUBCLASS;
104+
}
105+
if ty_inner.is_subtype(exp_zoo.base_exception_type) {
106+
flags |= PY_TPFLAGS_BASE_EXC_SUBCLASS;
107+
}
108+
if ty_inner.is_subtype(zoo.type_type) {
109+
flags |= PY_TPFLAGS_TYPE_SUBCLASS;
110+
}
111+
112+
flags
103113
}
104114

105115
#[unsafe(no_mangle)]

crates/vm/src/builtins/type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ impl PyType {
12401240
}
12411241

12421242
impl Py<PyType> {
1243-
pub(crate) fn is_subtype(&self, other: &Self) -> bool {
1243+
pub fn is_subtype(&self, other: &Self) -> bool {
12441244
is_subtype_with_mro(&self.mro.read(), self, other)
12451245
}
12461246

0 commit comments

Comments
 (0)