mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Add _types module (#6807)
* _types * builtin_function_or_method * PyCapsule * function_or_method * Remove expectedFailure for test_builtin_function and test_join_nondaemon_on_shutdown
This commit is contained in:
1
Lib/test/test_reprlib.py
vendored
1
Lib/test/test_reprlib.py
vendored
@@ -207,7 +207,6 @@ class ReprTests(unittest.TestCase):
|
||||
self.assertStartsWith(r, "<function ReprTests.test_lambda.<locals>.<lambda")
|
||||
# XXX anonymous functions? see func_repr
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_builtin_function(self):
|
||||
eq = self.assertEqual
|
||||
# Functions
|
||||
|
||||
1
Lib/test/test_threading.py
vendored
1
Lib/test/test_threading.py
vendored
@@ -492,7 +492,6 @@ class ThreadTests(BaseTestCase):
|
||||
sys.settrace(func)
|
||||
""")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_join_nondaemon_on_shutdown(self):
|
||||
# Issue 1722344
|
||||
# Raising SystemExit skipped threading._shutdown
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::{
|
||||
use alloc::fmt;
|
||||
|
||||
// PyCFunctionObject in CPython
|
||||
#[repr(C)]
|
||||
#[pyclass(name = "builtin_function_or_method", module = false)]
|
||||
pub struct PyNativeFunction {
|
||||
pub(crate) value: &'static PyMethodDef,
|
||||
@@ -68,13 +69,65 @@ impl Callable for PyNativeFunction {
|
||||
#[inline]
|
||||
fn call(zelf: &Py<Self>, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(z) = &zelf.zelf {
|
||||
args.prepend_arg(z.clone());
|
||||
// STATIC methods store the class in zelf for qualname/repr purposes,
|
||||
// but should not prepend it to args (the Rust function doesn't expect it).
|
||||
if !zelf.value.flags.contains(PyMethodFlags::STATIC) {
|
||||
args.prepend_arg(z.clone());
|
||||
}
|
||||
}
|
||||
(zelf.value.func)(vm, args)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Callable), flags(HAS_DICT, DISALLOW_INSTANTIATION))]
|
||||
// meth_richcompare in CPython
|
||||
impl Comparable for PyNativeFunction {
|
||||
fn cmp(
|
||||
zelf: &Py<Self>,
|
||||
other: &PyObject,
|
||||
op: PyComparisonOp,
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
op.eq_only(|| {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
let eq = match (zelf.zelf.as_ref(), other.zelf.as_ref()) {
|
||||
(Some(z), Some(o)) => z.is(o),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
};
|
||||
let eq = eq && core::ptr::eq(zelf.value, other.value);
|
||||
Ok(eq.into())
|
||||
} else {
|
||||
Ok(PyComparisonValue::NotImplemented)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// meth_repr in CPython
|
||||
impl Representable for PyNativeFunction {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
if let Some(bound) = zelf
|
||||
.zelf
|
||||
.as_ref()
|
||||
.filter(|b| !b.class().is(vm.ctx.types.module_type))
|
||||
{
|
||||
Ok(format!(
|
||||
"<built-in method {} of {} object at {:#x}>",
|
||||
zelf.value.name,
|
||||
bound.class().name(),
|
||||
bound.get_id()
|
||||
))
|
||||
} else {
|
||||
Ok(format!("<built-in function {}>", zelf.value.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
with(Callable, Comparable, Representable),
|
||||
flags(HAS_DICT, DISALLOW_INSTANTIATION)
|
||||
)]
|
||||
impl PyNativeFunction {
|
||||
#[pygetset]
|
||||
fn __module__(zelf: NativeFunctionOrMethod) -> Option<&'static PyStrInterned> {
|
||||
@@ -86,20 +139,19 @@ impl PyNativeFunction {
|
||||
zelf.0.value.name
|
||||
}
|
||||
|
||||
// meth_get__qualname__ in CPython
|
||||
#[pygetset]
|
||||
fn __qualname__(zelf: NativeFunctionOrMethod, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
let zelf = zelf.0;
|
||||
let flags = zelf.value.flags;
|
||||
// if flags.contains(PyMethodFlags::CLASS) || flags.contains(PyMethodFlags::STATIC) {
|
||||
let qualname = if let Some(bound) = &zelf.zelf {
|
||||
let prefix = if flags.contains(PyMethodFlags::CLASS) {
|
||||
bound
|
||||
.get_attr("__qualname__", vm)
|
||||
.unwrap()
|
||||
.str(vm)
|
||||
.unwrap()
|
||||
.to_string()
|
||||
if bound.class().is(vm.ctx.types.module_type) {
|
||||
return Ok(vm.ctx.intern_str(zelf.value.name).to_owned());
|
||||
}
|
||||
let prefix = if bound.class().is(vm.ctx.types.type_type) {
|
||||
// m_self is a type: use PyType_GetQualName(m_self)
|
||||
bound.get_attr("__qualname__", vm)?.str(vm)?.to_string()
|
||||
} else {
|
||||
// m_self is an instance: use Py_TYPE(m_self).__qualname__
|
||||
bound.class().name().to_string()
|
||||
};
|
||||
vm.ctx.new_str(format!("{}.{}", prefix, &zelf.value.name))
|
||||
@@ -114,15 +166,23 @@ impl PyNativeFunction {
|
||||
zelf.0.value.doc
|
||||
}
|
||||
|
||||
// meth_get__self__ in CPython
|
||||
#[pygetset]
|
||||
fn __self__(_zelf: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.none()
|
||||
fn __self__(zelf: NativeFunctionOrMethod, vm: &VirtualMachine) -> PyObjectRef {
|
||||
zelf.0.zelf.clone().unwrap_or_else(|| vm.ctx.none())
|
||||
}
|
||||
|
||||
// meth_reduce in CPython
|
||||
#[pymethod]
|
||||
const fn __reduce__(&self) -> &'static str {
|
||||
// TODO: return (getattr, (self.object, self.name)) if this is a method
|
||||
self.value.name
|
||||
fn __reduce__(zelf: NativeFunctionOrMethod, vm: &VirtualMachine) -> PyResult {
|
||||
let zelf = zelf.0;
|
||||
if zelf.zelf.is_none() || zelf.module.is_some() {
|
||||
Ok(vm.ctx.new_str(zelf.value.name).into())
|
||||
} else {
|
||||
let getattr = vm.builtins.get_attr("getattr", vm)?;
|
||||
let target = zelf.zelf.clone().unwrap();
|
||||
Ok(vm.new_tuple((getattr, (target, zelf.value.name))).into())
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -138,54 +198,20 @@ impl PyNativeFunction {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyNativeFunction {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok(format!("<built-in function {}>", zelf.value.name))
|
||||
}
|
||||
}
|
||||
|
||||
// `PyCMethodObject` in CPython
|
||||
#[pyclass(name = "builtin_method", module = false, base = PyNativeFunction, ctx = "builtin_method_type")]
|
||||
// PyCMethodObject in CPython
|
||||
// repr(C) ensures `func` is at offset 0, allowing safe cast from PyNativeMethod to PyNativeFunction
|
||||
#[repr(C)]
|
||||
#[pyclass(name = "builtin_function_or_method", module = false, base = PyNativeFunction, ctx = "builtin_function_or_method_type")]
|
||||
pub struct PyNativeMethod {
|
||||
pub(crate) func: PyNativeFunction,
|
||||
pub(crate) class: &'static Py<PyType>, // TODO: the actual life is &'self
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
with(Callable, Comparable, Representable),
|
||||
flags(HAS_DICT, DISALLOW_INSTANTIATION)
|
||||
)]
|
||||
impl PyNativeMethod {
|
||||
#[pygetset]
|
||||
fn __qualname__(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
let prefix = zelf.class.name().to_string();
|
||||
Ok(vm
|
||||
.ctx
|
||||
.new_str(format!("{}.{}", prefix, &zelf.func.value.name)))
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __reduce__(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(PyObjectRef, (PyObjectRef, &'static str))> {
|
||||
// TODO: return (getattr, (self.object, self.name)) if this is a method
|
||||
let getattr = vm.builtins.get_attr("getattr", vm)?;
|
||||
let target = self
|
||||
.func
|
||||
.zelf
|
||||
.clone()
|
||||
.unwrap_or_else(|| self.class.to_owned().into());
|
||||
let name = self.func.value.name;
|
||||
Ok((getattr, (target, name)))
|
||||
}
|
||||
|
||||
#[pygetset]
|
||||
fn __self__(zelf: PyRef<Self>, _vm: &VirtualMachine) -> Option<PyObjectRef> {
|
||||
zelf.func.zelf.clone()
|
||||
}
|
||||
}
|
||||
// All Python-visible behavior (getters, slots) is registered by PyNativeFunction::extend_class.
|
||||
// PyNativeMethod only extends the Rust-side struct with the defining class reference.
|
||||
// The func field at offset 0 (#[repr(C)]) allows NativeFunctionOrMethod to read it safely.
|
||||
#[pyclass(flags(HAS_DICT, DISALLOW_INSTANTIATION))]
|
||||
impl PyNativeMethod {}
|
||||
|
||||
impl fmt::Debug for PyNativeMethod {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
@@ -198,63 +224,21 @@ impl fmt::Debug for PyNativeMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl Comparable for PyNativeMethod {
|
||||
fn cmp(
|
||||
zelf: &Py<Self>,
|
||||
other: &PyObject,
|
||||
op: PyComparisonOp,
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
op.eq_only(|| {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
let eq = match (zelf.func.zelf.as_ref(), other.func.zelf.as_ref()) {
|
||||
(Some(z), Some(o)) => z.is(o),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
};
|
||||
let eq = eq && core::ptr::eq(zelf.func.value, other.func.value);
|
||||
Ok(eq.into())
|
||||
} else {
|
||||
Ok(PyComparisonValue::NotImplemented)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Callable for PyNativeMethod {
|
||||
type Args = FuncArgs;
|
||||
|
||||
#[inline]
|
||||
fn call(zelf: &Py<Self>, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(zelf) = &zelf.func.zelf {
|
||||
args.prepend_arg(zelf.clone());
|
||||
}
|
||||
(zelf.func.value.func)(vm, args)
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyNativeMethod {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok(format!(
|
||||
"<built-in method {} of {} object at ...>",
|
||||
&zelf.func.value.name,
|
||||
zelf.class.name()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &Context) {
|
||||
PyNativeFunction::extend_class(context, context.types.builtin_function_or_method_type);
|
||||
PyNativeMethod::extend_class(context, context.types.builtin_method_type);
|
||||
}
|
||||
|
||||
/// Wrapper that provides access to the common PyNativeFunction data
|
||||
/// for both PyNativeFunction and PyNativeMethod (which has func as its first field).
|
||||
struct NativeFunctionOrMethod(PyRef<PyNativeFunction>);
|
||||
|
||||
impl TryFromObject for NativeFunctionOrMethod {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let class = vm.ctx.types.builtin_function_or_method_type;
|
||||
if obj.fast_isinstance(class) {
|
||||
// Both PyNativeFunction and PyNativeMethod share the same type now.
|
||||
// PyNativeMethod has `func: PyNativeFunction` as its first field,
|
||||
// so we can safely treat the data pointer as PyNativeFunction for reading.
|
||||
Ok(Self(unsafe { obj.downcast_unchecked() }))
|
||||
} else {
|
||||
Err(vm.new_downcast_type_error(class, &obj))
|
||||
|
||||
33
crates/vm/src/builtins/capsule.rs
Normal file
33
crates/vm/src/builtins/capsule.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use super::PyType;
|
||||
use crate::{Context, Py, PyPayload, PyResult, class::PyClassImpl, types::Representable};
|
||||
|
||||
/// PyCapsule - a container for C pointers.
|
||||
/// In RustPython, this is a minimal implementation for compatibility.
|
||||
#[pyclass(module = false, name = "PyCapsule")]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PyCapsule {
|
||||
// Capsules store opaque pointers; we don't expose the actual pointer functionality
|
||||
// since RustPython doesn't have the same C extension model as CPython.
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl PyPayload for PyCapsule {
|
||||
#[inline]
|
||||
fn class(ctx: &Context) -> &'static Py<PyType> {
|
||||
ctx.types.capsule_type
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Representable), flags(DISALLOW_INSTANTIATION))]
|
||||
impl PyCapsule {}
|
||||
|
||||
impl Representable for PyCapsule {
|
||||
#[inline]
|
||||
fn repr_str(_zelf: &Py<Self>, _vm: &crate::VirtualMachine) -> PyResult<String> {
|
||||
Ok("<capsule object>".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &Context) {
|
||||
PyCapsule::extend_class(context, context.types.capsule_type);
|
||||
}
|
||||
@@ -9,6 +9,8 @@ pub(crate) mod bytearray;
|
||||
pub use bytearray::PyByteArray;
|
||||
pub(crate) mod bytes;
|
||||
pub use bytes::{PyBytes, PyBytesRef};
|
||||
pub(crate) mod capsule;
|
||||
pub use capsule::PyCapsule;
|
||||
pub(crate) mod classmethod;
|
||||
pub use classmethod::PyClassMethod;
|
||||
pub(crate) mod code;
|
||||
|
||||
@@ -188,7 +188,7 @@ impl PyMethodDef {
|
||||
) -> PyRef<PyNativeMethod> {
|
||||
PyRef::new_ref(
|
||||
self.to_bound_method(obj, class),
|
||||
ctx.types.builtin_method_type.to_owned(),
|
||||
ctx.types.builtin_function_or_method_type.to_owned(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
@@ -211,7 +211,13 @@ impl PyMethodDef {
|
||||
class: &'static Py<PyType>,
|
||||
) -> PyRef<PyNativeMethod> {
|
||||
debug_assert!(self.flags.contains(PyMethodFlags::STATIC));
|
||||
let func = self.to_function();
|
||||
// Set zelf to the class, matching CPython's m_self = type for static methods.
|
||||
// Callable::call skips prepending when STATIC flag is set.
|
||||
let func = PyNativeFunction {
|
||||
zelf: Some(class.to_owned().into()),
|
||||
value: self,
|
||||
module: None,
|
||||
};
|
||||
PyNativeMethod { func, class }.into_ref(ctx)
|
||||
}
|
||||
|
||||
|
||||
157
crates/vm/src/stdlib/_types.rs
Normal file
157
crates/vm/src/stdlib/_types.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
//! Implementation of the `_types` module.
|
||||
//!
|
||||
//! This module exposes built-in types that are used by the `types` module.
|
||||
|
||||
pub(crate) use _types::module_def;
|
||||
|
||||
#[pymodule]
|
||||
#[allow(non_snake_case)]
|
||||
mod _types {
|
||||
use crate::{PyObjectRef, VirtualMachine};
|
||||
|
||||
#[pyattr]
|
||||
fn AsyncGeneratorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.async_generator.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn BuiltinFunctionType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx
|
||||
.types
|
||||
.builtin_function_or_method_type
|
||||
.to_owned()
|
||||
.into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn BuiltinMethodType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
// Same as BuiltinFunctionType in CPython
|
||||
vm.ctx
|
||||
.types
|
||||
.builtin_function_or_method_type
|
||||
.to_owned()
|
||||
.into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn CapsuleType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.capsule_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn CellType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.cell_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn CodeType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.code_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn CoroutineType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.coroutine_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn EllipsisType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.ellipsis_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn FrameType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.frame_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn FunctionType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.function_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn GeneratorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.generator_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn GenericAlias(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.generic_alias_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn GetSetDescriptorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.getset_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn LambdaType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
// Same as FunctionType in CPython
|
||||
vm.ctx.types.function_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn MappingProxyType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.mappingproxy_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn MemberDescriptorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.member_descriptor_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn MethodDescriptorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.method_descriptor_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn ClassMethodDescriptorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
// TODO: implement as separate type
|
||||
vm.ctx.types.method_descriptor_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn MethodType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.bound_method_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn MethodWrapperType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.method_wrapper_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn ModuleType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.module_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn NoneType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.none_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn NotImplementedType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.not_implemented_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn SimpleNamespace(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.namespace_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn TracebackType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.traceback_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn UnionType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.union_type.to_owned().into()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
fn WrapperDescriptorType(vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx.types.wrapper_descriptor_type.to_owned().into()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
mod _abc;
|
||||
mod _types;
|
||||
#[cfg(feature = "ast")]
|
||||
pub(crate) mod ast;
|
||||
pub mod atexit;
|
||||
@@ -73,6 +74,7 @@ use crate::{Context, builtins::PyModuleDef};
|
||||
pub fn builtin_module_defs(ctx: &Context) -> Vec<&'static PyModuleDef> {
|
||||
vec![
|
||||
_abc::module_def(ctx),
|
||||
_types::module_def(ctx),
|
||||
#[cfg(feature = "ast")]
|
||||
ast::module_def(ctx),
|
||||
atexit::module_def(ctx),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
Py,
|
||||
builtins::{
|
||||
asyncgenerator, bool_, builtin_func, bytearray, bytes, classmethod, code, complex,
|
||||
asyncgenerator, bool_, builtin_func, bytearray, bytes, capsule, classmethod, code, complex,
|
||||
coroutine, descriptor, dict, enumerate, filter, float, frame, function, generator,
|
||||
genericalias, getset, int, interpolation, iter, list, map, mappingproxy, memory, module,
|
||||
namespace, object, property, pystr, range, set, singletons, slice, staticmethod, super_,
|
||||
@@ -28,6 +28,7 @@ pub struct TypeZoo {
|
||||
pub bytearray_iterator_type: &'static Py<PyType>,
|
||||
pub bool_type: &'static Py<PyType>,
|
||||
pub callable_iterator: &'static Py<PyType>,
|
||||
pub capsule_type: &'static Py<PyType>,
|
||||
pub cell_type: &'static Py<PyType>,
|
||||
pub classmethod_type: &'static Py<PyType>,
|
||||
pub code_type: &'static Py<PyType>,
|
||||
@@ -108,12 +109,20 @@ impl TypeZoo {
|
||||
#[cold]
|
||||
pub(crate) fn init() -> Self {
|
||||
let (type_type, object_type, weakref_type) = crate::object::init_type_hierarchy();
|
||||
// the order matters for type, object, weakref, and int - must be initialized first
|
||||
let type_type = type_::PyType::init_manually(type_type);
|
||||
let object_type = object::PyBaseObject::init_manually(object_type);
|
||||
let weakref_type = weakref::PyWeak::init_manually(weakref_type);
|
||||
let int_type = int::PyInt::init_builtin_type();
|
||||
|
||||
// builtin_function_or_method and builtin_method share the same type (CPython behavior)
|
||||
let builtin_function_or_method_type = builtin_func::PyNativeFunction::init_builtin_type();
|
||||
|
||||
Self {
|
||||
// the order matters for type, object, weakref, and int
|
||||
type_type: type_::PyType::init_manually(type_type),
|
||||
object_type: object::PyBaseObject::init_manually(object_type),
|
||||
weakref_type: weakref::PyWeak::init_manually(weakref_type),
|
||||
int_type: int::PyInt::init_builtin_type(),
|
||||
type_type,
|
||||
object_type,
|
||||
weakref_type,
|
||||
int_type,
|
||||
|
||||
// types exposed as builtins
|
||||
bool_type: bool_::PyBool::init_builtin_type(),
|
||||
@@ -147,11 +156,12 @@ impl TypeZoo {
|
||||
asyncgenerator::PyAsyncGenWrappedValue::init_builtin_type(),
|
||||
anext_awaitable: asyncgenerator::PyAnextAwaitable::init_builtin_type(),
|
||||
bound_method_type: function::PyBoundMethod::init_builtin_type(),
|
||||
builtin_function_or_method_type: builtin_func::PyNativeFunction::init_builtin_type(),
|
||||
builtin_method_type: builtin_func::PyNativeMethod::init_builtin_type(),
|
||||
builtin_function_or_method_type,
|
||||
builtin_method_type: builtin_function_or_method_type,
|
||||
bytearray_iterator_type: bytearray::PyByteArrayIterator::init_builtin_type(),
|
||||
bytes_iterator_type: bytes::PyBytesIterator::init_builtin_type(),
|
||||
callable_iterator: iter::PyCallableIterator::init_builtin_type(),
|
||||
capsule_type: capsule::PyCapsule::init_builtin_type(),
|
||||
cell_type: function::PyCell::init_builtin_type(),
|
||||
code_type: code::PyCode::init_builtin_type(),
|
||||
coroutine_type: coroutine::PyCoroutine::init_builtin_type(),
|
||||
@@ -225,6 +235,7 @@ impl TypeZoo {
|
||||
complex::init(context);
|
||||
bytes::init(context);
|
||||
bytearray::init(context);
|
||||
capsule::init(context);
|
||||
property::init(context);
|
||||
getset::init(context);
|
||||
memory::init(context);
|
||||
|
||||
Reference in New Issue
Block a user