Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8053d7b

Browse filesBrowse files
darleybarretoyouknowone
authored andcommitted
Adding PyCArray's from_param
1 parent e6f737a commit 8053d7b
Copy full SHA for 8053d7b

File tree

4 files changed

+111
-18
lines changed
Filter options

4 files changed

+111
-18
lines changed

‎Lib/ctypes/__init__.py

Copy file name to clipboardExpand all lines: Lib/ctypes/__init__.py
+41-1Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"""create and manipulate C data types in Python"""
33

44
import os as _os, sys as _sys
5-
import types as _types
65

76
__version__ = "1.1.0"
87

@@ -307,3 +306,44 @@ def __getitem__(self, name):
307306

308307
def LoadLibrary(self, name):
309308
return self._dlltype(name)
309+
310+
cdll = LibraryLoader(CDLL)
311+
312+
if _os.name == "nt":
313+
windll = LibraryLoader(CDLL)
314+
oledll = LibraryLoader(CDLL)
315+
316+
GetLastError = windll.kernel32.GetLastError
317+
318+
def WinError(code=None, descr=None):
319+
if code is None:
320+
code = GetLastError()
321+
if descr is None:
322+
# descr = FormatError(code).strip()
323+
descr = "Windows Error " + str(code)
324+
return OSError(None, descr, None, code)
325+
326+
if sizeof(c_uint) == sizeof(c_void_p):
327+
c_size_t = c_uint
328+
c_ssize_t = c_int
329+
elif sizeof(c_ulong) == sizeof(c_void_p):
330+
c_size_t = c_ulong
331+
c_ssize_t = c_long
332+
elif sizeof(c_ulonglong) == sizeof(c_void_p):
333+
c_size_t = c_ulonglong
334+
c_ssize_t = c_longlong
335+
336+
# Fill in specifically-sized types
337+
c_int8 = c_byte
338+
c_uint8 = c_ubyte
339+
for kind in [c_short, c_int, c_long, c_longlong]:
340+
if sizeof(kind) == 2: c_int16 = kind
341+
elif sizeof(kind) == 4: c_int32 = kind
342+
elif sizeof(kind) == 8: c_int64 = kind
343+
for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
344+
if sizeof(kind) == 2: c_uint16 = kind
345+
elif sizeof(kind) == 4: c_uint32 = kind
346+
elif sizeof(kind) == 8: c_uint64 = kind
347+
del(kind)
348+
349+
_reset_cache()

‎vm/src/stdlib/ctypes/array.rs

Copy file name to clipboardExpand all lines: vm/src/stdlib/ctypes/array.rs
+68-16Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use num_bigint::Sign;
55
use widestring::WideCString;
66

77
use crate::builtins::memory::{try_buffer_from_object, Buffer};
8-
use crate::builtins::slice::PySliceRef;
8+
use crate::builtins::slice::PySlice;
99
use crate::builtins::{PyBytes, PyInt, PyList, PyStr, PyTypeRef};
1010
use crate::common::borrow::BorrowedValueMut;
1111
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
12-
use crate::function::{FuncArgs, OptionalArg};
12+
use crate::function::OptionalArg;
1313
use crate::pyobject::{
1414
BorrowValue, Either, IdProtocol, PyObjectRef, PyRef, PyResult, PyValue, StaticType,
1515
TryFromObject, TypeProtocol,
@@ -18,8 +18,8 @@ use crate::slots::BufferProtocol;
1818
use crate::VirtualMachine;
1919

2020
use crate::stdlib::ctypes::basics::{
21-
generic_get_buffer, get_size, BorrowValue as BorrowValueCData, BorrowValueMut, PyCData,
22-
PyCDataFunctions, PyCDataMethods, RawBuffer,
21+
default_from_param, generic_get_buffer, get_size, BorrowValue as BorrowValueCData,
22+
BorrowValueMut, PyCData, PyCDataFunctions, PyCDataMethods, RawBuffer,
2323
};
2424
use crate::stdlib::ctypes::pointer::PyCPointer;
2525
use crate::stdlib::ctypes::primitive::PySimpleType;
@@ -169,7 +169,7 @@ fn set_array_value(
169169
}
170170

171171
fn array_get_slice_inner(
172-
slice: PySliceRef,
172+
slice: PyRef<PySlice>,
173173
vm: &VirtualMachine,
174174
) -> PyResult<(isize, isize, isize)> {
175175
let step = slice
@@ -236,11 +236,41 @@ impl BufferProtocol for PyCArray {
236236
}
237237
}
238238

239-
// impl PyCDataMethods for PyCArray {
240-
// fn from_param(zelf: PyRef<Self>, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
239+
impl PyCDataMethods for PyCArray {
240+
fn from_param(
241+
zelf: PyRef<Self>,
242+
value: PyObjectRef,
243+
vm: &VirtualMachine,
244+
) -> PyResult<PyObjectRef> {
245+
if vm.isinstance(&value, PyCArray::static_type())? {
246+
return Ok(value);
247+
};
248+
249+
if vm.obj_len(&value)? > zelf._length_ {
250+
Err(vm.new_value_error("Invalid length".to_string()))
251+
} else if zelf._type_._type_.as_str() == "c"
252+
&& value.clone().downcast_exact::<PyBytes>(vm).is_err()
253+
{
254+
Err(vm.new_value_error(format!("expected bytes, {} found", value.class().name)))
255+
} else if zelf._type_._type_.as_str() == "u"
256+
&& value.clone().downcast_exact::<PyStr>(vm).is_err()
257+
{
258+
Err(vm.new_value_error(format!(
259+
"expected unicode string, {} found",
260+
value.class().name
261+
)))
262+
} else if vm.isinstance(&value, &vm.ctx.types.tuple_type)? {
263+
Ok(())
264+
} else {
265+
//@TODO: make sure what goes here
266+
Err(vm.new_type_error("Invalid type".to_string()))
267+
}?;
241268

242-
// }
243-
// }
269+
PyCArray::init(zelf.clone(), value, vm)?;
270+
271+
default_from_param(zelf.clone_class(), zelf.as_object().clone(), vm)
272+
}
273+
}
244274

245275
#[pyimpl(flags(BASETYPE), with(BufferProtocol))]
246276
impl PyCArray {
@@ -274,9 +304,31 @@ impl PyCArray {
274304
}
275305

276306
#[pymethod(magic)]
277-
pub fn init(&self, value: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
278-
// @TODO
279-
Ok(())
307+
pub fn init(zelf: PyRef<Self>, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
308+
let value_lenght = vm.obj_len(&value)?;
309+
310+
if value_lenght < zelf._length_ {
311+
let value_vec: Vec<PyObjectRef> = vm.extract_elements(&value)?;
312+
for (i, v) in value_vec.iter().enumerate() {
313+
Self::setitem(zelf.clone(), Either::A(i as isize), v.clone(), vm)?
314+
}
315+
Ok(())
316+
} else if value_lenght == zelf._length_ {
317+
let py_slice = Either::B(
318+
PySlice {
319+
start: Some(vm.new_pyobj(0)),
320+
stop: vm.new_pyobj(zelf._length_),
321+
step: None,
322+
}
323+
.into_ref(vm),
324+
);
325+
326+
Self::setitem(zelf, py_slice, value, vm)
327+
} else {
328+
Err(vm.new_value_error(
329+
"number of values is greater than the size of the array".to_string(),
330+
))
331+
}
280332
}
281333

282334
#[pyproperty(name = "value")]
@@ -440,7 +492,7 @@ impl PyCArray {
440492
#[pymethod(magic)]
441493
fn getitem(
442494
zelf: PyRef<Self>,
443-
k_or_idx: Either<isize, PySliceRef>,
495+
k_or_idx: Either<isize, PyRef<PySlice>>,
444496
vm: &VirtualMachine,
445497
) -> PyResult {
446498
let buffer = try_buffer_from_object(vm, zelf.as_object())?;
@@ -484,7 +536,7 @@ impl PyCArray {
484536
#[pymethod(magic)]
485537
fn setitem(
486538
zelf: PyRef<Self>,
487-
k_or_idx: Either<isize, PySliceRef>,
539+
k_or_idx: Either<isize, PyRef<PySlice>>,
488540
obj: PyObjectRef,
489541
vm: &VirtualMachine,
490542
) -> PyResult<()> {
@@ -511,7 +563,7 @@ impl PyCArray {
511563
let values: Vec<PyObjectRef> = vm.extract_elements(&obj)?;
512564

513565
if values.len() != slice_length {
514-
Err(vm.new_value_error("Can only assign sequence of same size".to_string()))
566+
Err(vm.new_value_error("can only assign sequence of same size".to_string()))
515567
} else {
516568
let mut cur = start as usize;
517569

@@ -550,7 +602,7 @@ impl PyCDataFunctions for PyCArray {
550602
.into_option()
551603
.map_or(Ok(0), |o| usize::try_from_object(vm, o))?;
552604

553-
if off_set > zelf._length_ {
605+
if off_set > zelf._length_ * get_size(zelf._type_._type_.as_str()) {
554606
Err(vm.new_index_error("offset out of bounds".to_string()))
555607
} else {
556608
let guard = zelf.borrow_value();

‎vm/src/stdlib/ctypes/basics.rs

Copy file name to clipboardExpand all lines: vm/src/stdlib/ctypes/basics.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub fn default_from_param(
165165
value: PyObjectRef,
166166
vm: &VirtualMachine,
167167
) -> PyResult<PyObjectRef> {
168+
//@TODO: check if this behaves like it should
168169
if vm.isinstance(&value, &cls)? {
169170
Ok(value)
170171
} else if let Ok(parameter) = vm.get_attribute(value.clone(), "_as_parameter_") {

‎vm/src/stdlib/ctypes/function.rs

Copy file name to clipboardExpand all lines: vm/src/stdlib/ctypes/function.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ impl PyCFuncPtr {
281281
if vm.isinstance(&argtypes, &vm.ctx.types.list_type).is_ok()
282282
|| vm.isinstance(&argtypes, &vm.ctx.types.tuple_type).is_ok()
283283
{
284-
let args: Vec<PyObjectRef> = vm.extract_elements(&argtypes)?;
284+
let args = vm.extract_elements(&argtypes)?;
285285
let c_args_res: PyResult<Vec<PyObjectRef>> = args
286286
.iter()
287287
.enumerate()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.