From cd89aa51f0cdc1482dc12f5560b0560a49f9ee01 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" <69878+youknowone@users.noreply.github.com> Date: Thu, 27 Mar 2025 19:45:04 +0900 Subject: [PATCH] Fix _ctypes.Array base and metaclass (#5620) --- .../{builtins_ctypes.py => stdlib_ctypes.py} | 5 ++++- vm/src/stdlib/ctypes.rs | 6 +++--- vm/src/stdlib/ctypes/array.rs | 18 +++++++++++++----- vm/src/stdlib/ctypes/base.rs | 8 ++++---- vm/src/stdlib/ctypes/structure.rs | 3 ++- vm/src/stdlib/ctypes/union.rs | 5 ++++- 6 files changed, 30 insertions(+), 15 deletions(-) rename extra_tests/snippets/{builtins_ctypes.py => stdlib_ctypes.py} (98%) diff --git a/extra_tests/snippets/builtins_ctypes.py b/extra_tests/snippets/stdlib_ctypes.py similarity index 98% rename from extra_tests/snippets/builtins_ctypes.py rename to extra_tests/snippets/stdlib_ctypes.py index 2108ce41a..95ee9900f 100644 --- a/extra_tests/snippets/builtins_ctypes.py +++ b/extra_tests/snippets/stdlib_ctypes.py @@ -3,12 +3,15 @@ import types as _types from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import sizeof -from _ctypes import _SimpleCData +from _ctypes import _SimpleCData, Array from _ctypes import CFuncPtr as _CFuncPtr from struct import calcsize as _calcsize +assert Array.__class__.__name__ == 'PyCArrayType' +assert Array.__base__.__name__ == '_CData' + DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode diff --git a/vm/src/stdlib/ctypes.rs b/vm/src/stdlib/ctypes.rs index 38955fe39..235e089e3 100644 --- a/vm/src/stdlib/ctypes.rs +++ b/vm/src/stdlib/ctypes.rs @@ -10,16 +10,16 @@ pub(crate) mod union; use crate::builtins::PyModule; use crate::class::PyClassImpl; -use crate::stdlib::ctypes::base::{PyCData, PyCSimple, PySimpleMeta}; +use crate::stdlib::ctypes::base::{PyCData, PyCSimple, PyCSimpleType}; use crate::{Py, PyRef, VirtualMachine}; pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py) { let ctx = &vm.ctx; - PySimpleMeta::make_class(ctx); + PyCSimpleType::make_class(ctx); + array::PyCArrayType::make_class(ctx); extend_module!(vm, module, { "_CData" => PyCData::make_class(ctx), "_SimpleCData" => PyCSimple::make_class(ctx), - "ArrayType" => array::PyCArrayType::make_class(ctx), "Array" => array::PyCArray::make_class(ctx), "CFuncPtr" => function::PyCFuncPtr::make_class(ctx), "_Pointer" => pointer::PyCPointer::make_class(ctx), diff --git a/vm/src/stdlib/ctypes/array.rs b/vm/src/stdlib/ctypes/array.rs index 44d237cd7..0880c6b63 100644 --- a/vm/src/stdlib/ctypes/array.rs +++ b/vm/src/stdlib/ctypes/array.rs @@ -1,13 +1,16 @@ use crate::builtins::PyBytes; use crate::types::Callable; use crate::{Py, PyObjectRef, PyPayload}; -use crate::{PyResult, VirtualMachine, builtins::PyTypeRef, types::Constructor}; +use crate::{ + PyResult, VirtualMachine, + builtins::{PyType, PyTypeRef}, + types::Constructor, +}; use crossbeam_utils::atomic::AtomicCell; use rustpython_common::lock::PyRwLock; -use rustpython_vm::stdlib::ctypes::base::PyCSimple; +use rustpython_vm::stdlib::ctypes::base::PyCData; -// TODO: make it metaclass -#[pyclass(name = "ArrayType", module = "_ctypes")] +#[pyclass(name = "PyCArrayType", base = "PyType", module = "_ctypes")] #[derive(PyPayload)] pub struct PyCArrayType { pub(super) inner: PyCArray, @@ -44,7 +47,12 @@ impl Constructor for PyCArrayType { #[pyclass(flags(IMMUTABLETYPE), with(Callable, Constructor))] impl PyCArrayType {} -#[pyclass(name = "Array", base = "PyCSimple", module = "_ctypes")] +#[pyclass( + name = "Array", + base = "PyCData", + metaclass = "PyCArrayType", + module = "_ctypes" +)] #[derive(PyPayload)] pub struct PyCArray { pub(super) typ: PyRwLock, diff --git a/vm/src/stdlib/ctypes/base.rs b/vm/src/stdlib/ctypes/base.rs index e3e12bdf3..6cc19be3d 100644 --- a/vm/src/stdlib/ctypes/base.rs +++ b/vm/src/stdlib/ctypes/base.rs @@ -160,10 +160,10 @@ pub struct PyCData { impl PyCData {} #[pyclass(module = "_ctypes", name = "PyCSimpleType", base = "PyType")] -pub struct PySimpleMeta {} +pub struct PyCSimpleType {} #[pyclass(flags(BASETYPE))] -impl PySimpleMeta { +impl PyCSimpleType { #[allow(clippy::new_ret_no_self)] #[pymethod] fn new(cls: PyTypeRef, _: OptionalArg, vm: &VirtualMachine) -> PyResult { @@ -176,10 +176,10 @@ impl PySimpleMeta { } #[pyclass( + module = "_ctypes", name = "_SimpleCData", base = "PyCData", - module = "_ctypes", - metaclass = "PySimpleMeta" + metaclass = "PyCSimpleType" )] #[derive(PyPayload)] pub struct PyCSimple { diff --git a/vm/src/stdlib/ctypes/structure.rs b/vm/src/stdlib/ctypes/structure.rs index c6cf15895..10c1fa3df 100644 --- a/vm/src/stdlib/ctypes/structure.rs +++ b/vm/src/stdlib/ctypes/structure.rs @@ -1,3 +1,4 @@ +use super::base::PyCData; use crate::builtins::{PyList, PyStr, PyTuple, PyTypeRef}; use crate::function::FuncArgs; use crate::types::GetAttr; @@ -7,7 +8,7 @@ use rustpython_vm::types::Constructor; use std::collections::HashMap; use std::fmt::Debug; -#[pyclass(name = "Structure", module = "_ctypes")] +#[pyclass(module = "_ctypes", name = "Structure", base = "PyCData")] #[derive(PyPayload, Debug)] pub struct PyCStructure { #[allow(dead_code)] diff --git a/vm/src/stdlib/ctypes/union.rs b/vm/src/stdlib/ctypes/union.rs index 5a39d9062..2d76dbc9c 100644 --- a/vm/src/stdlib/ctypes/union.rs +++ b/vm/src/stdlib/ctypes/union.rs @@ -1,4 +1,7 @@ -#[pyclass(name = "Union", module = "_ctypes")] +use super::base::PyCData; + +// TODO: metaclass = "UnionType" +#[pyclass(module = "_ctypes", name = "Union", base = "PyCData")] pub struct PyCUnion {} #[pyclass(flags(BASETYPE, IMMUTABLETYPE))]