8000 _ctypes addressof and Structure (#5573) · RustPython/RustPython@8ff856d · GitHub
[go: up one dir, main page]

Skip to content

Commit 8ff856d

Browse files
authored
_ctypes addressof and Structure (#5573)
* _ctypes.addressof Signed-off-by: Ashwin Naren <arihant2math@gmail.com> * ctypes.Structure implementation Signed-off-by: Ashwin Naren <arihant2math@gmail.com> * clippy fix Signed-off-by: Ashwin Naren <arihant2math@gmail.com> * formatting Signed-off-by: Ashwin Naren <arihant2math@gmail.com> --------- Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
1 parent 6731c4b commit 8ff856d

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

vm/src/stdlib/ctypes.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,16 @@ pub(crate) mod _ctypes {
214214
}
215215
}
216216

217+
#[pyfunction]
218+
fn addressof(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
219+
if obj.is_instance(PyCSimple::static_type().as_ref(), vm)? {
220+
let simple = obj.downcast_ref::<PyCSimple>().unwrap();
221+
Ok(simple.value.as_ptr() as usize)
222+
} else {
223+
Err(vm.new_type_error("expected a ctypes instance".to_string()))
224+
}
225+
}
226+
217227
#[pyfunction]
218228
fn get_errno() -> i32 {
219229
errno::errno().0

vm/src/stdlib/ctypes/structure.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,61 @@
1+
use crate::builtins::{PyList, PyStr, PyTuple, PyTypeRef};
2+
use crate::function::FuncArgs;
3+
use crate::types::GetAttr;
4+
use crate::{AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine};
5+
use rustpython_common::lock::PyRwLock;
6+
use rustpython_vm::types::Constructor;
7+
use std::collections::HashMap;
8+
use std::fmt::Debug;
9+
110
#[pyclass(name = "Structure", module = "_ctypes")]
2-
pub struct PyCStructure {}
11+
#[derive(PyPayload, Debug)]
12+
pub struct PyCStructure {
13+
#[allow(dead_code)]
14+
field_data: PyRwLock<HashMap<String, PyObjectRef>>,
15+
data: PyRwLock<HashMap<String, PyObjectRef>>,
16+
}
17+
18+
impl Constructor for PyCStructure {
19+
type Args = FuncArgs;
20+
21+
fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
22+
let fields_attr = cls
23+
.get_class_attr(vm.ctx.interned_str("_fields_").unwrap())
24+
.ok_or_else(|| {
25+
vm.new_attribute_error("Structure must have a _fields_ attribute".to_string())
26+
})?;
27+
// downcast into list
28+
let fields = fields_attr.downcast_ref::<PyList>().ok_or_else(|| {
29+
vm.new_type_error("Structure _fields_ attribute must be a list".to_string())
30+
})?;
31+
let fields = fields.borrow_vec();
32+
let mut field_data = HashMap::new();
33+
for field in fields.iter() {
34+
let field = field
35+
.downcast_ref::<PyTuple>()
36+
.ok_or_else(|| vm.new_type_error("Field must be a tuple".to_string()))?;
37+
let name = field
38+
.first()
39+
.unwrap()
40+
.downcast_ref::<PyStr>()
41+
.ok_or_else(|| vm.new_type_error("Field name must be a string".to_string()))?;
42+
let typ = field.get(1).unwrap().clone();
43+
field_data.insert(name.as_str().to_string(), typ);
44+
}
45+
todo!("Implement PyCStructure::py_new")
46+
}
47+
}
48+
49+
impl GetAttr for PyCStructure {
50+
fn getattro(zelf: &Py<Self>, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
51+
let name = name.to_string();
52+
let data = zelf.data.read();
53+
match data.get(&name) {
54+
Some(value) => Ok(value.clone()),
55+
None => Err(vm.new_attribute_error(format!("No attribute named {}", name))),
56+
}
57+
}
58+
}
359

460
#[pyclass(flags(BASETYPE, IMMUTABLETYPE))]
561
impl PyCStructure {}

0 commit comments

Comments
 (0)
0