Skip to content

Commit 71410b6

Browse files
committed
fix mul
1 parent 5bf671d commit 71410b6

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

crates/vm/src/stdlib/ctypes/base.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,18 @@ impl Constructor for PyCSimple {
244244
let attributes = cls.get_attributes();
245245
let _type_ = attributes
246246
.iter()
247-
.find(|(k, _)| k.to_object().str(vm).unwrap().to_string() == *"_type_")
248-
.unwrap()
247+
.find(|(k, _)| {
248+
k.to_object()
249+
.str(vm)
250+
.map(|s| s.to_string() == "_type_")
251+
.unwrap_or(false)
252+
})
253+
.ok_or_else(|| {
254+
vm.new_type_error(format!(
255+
"cannot create '{}' instances: no _type_ attribute",
256+
cls.name()
257+
))
258+
})?
249259
.1
250260
.str(vm)?
251261
.to_string();

crates/vm/src/stdlib/ctypes/pointer.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
use crossbeam_utils::atomic::AtomicCell;
2+
use num_traits::ToPrimitive;
13
use rustpython_common::lock::PyRwLock;
24

3-
use crate::builtins::PyType;
5+
use crate::builtins::{PyType, PyTypeRef};
6+
use crate::convert::ToPyObject;
7+
use crate::protocol::PyNumberMethods;
48
use crate::stdlib::ctypes::PyCData;
5-
use crate::{PyObjectRef, PyResult};
9+
use crate::types::AsNumber;
10+
use crate::{PyObjectRef, PyResult, VirtualMachine};
611

712
#[pyclass(name = "PyCPointerType", base = PyType, module = "_ctypes")]
813
#[derive(PyPayload, Debug)]
@@ -11,8 +16,44 @@ pub struct PyCPointerType {
1116
pub(crate) inner: PyCPointer,
1217
}
1318

14-
#[pyclass]
15-
impl PyCPointerType {}
19+
#[pyclass(flags(IMMUTABLETYPE), with(AsNumber))]
20+
impl PyCPointerType {
21+
#[pymethod]
22+
fn __mul__(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult {
23+
use super::array::{PyCArray, PyCArrayType};
24+
if n < 0 {
25+
return Err(vm.new_value_error(format!("Array length must be >= 0, not {n}")));
26+
}
27+
Ok(PyCArrayType {
28+
inner: PyCArray {
29+
typ: PyRwLock::new(cls),
30+
length: AtomicCell::new(n as usize),
31+
value: PyRwLock::new(vm.ctx.none()),
32+
},
33+
}
34+
.to_pyobject(vm))
35+
}
36+
}
37+
38+
impl AsNumber for PyCPointerType {
39+
fn as_number() -> &'static PyNumberMethods {
40+
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
41+
multiply: Some(|a, b, vm| {
42+
let cls = a
43+
.downcast_ref::<PyType>()
44+
.ok_or_else(|| vm.new_type_error("expected type".to_owned()))?;
45+
let n = b
46+
.try_index(vm)?
47+
.as_bigint()
48+
.to_isize()
49+
.ok_or_else(|| vm.new_overflow_error("array size too large".to_owned()))?;
50+
PyCPointerType::__mul__(cls.to_owned(), n, vm)
51+
}),
52+
..PyNumberMethods::NOT_IMPLEMENTED
53+
};
54+
&AS_NUMBER
55+
}
56+
}
1657

1758
#[pyclass(
1859
name = "_Pointer",

0 commit comments

Comments
 (0)