11import ctypes
22from typing import Any , Dict , Type , Union
33
4+ from _pointers import force_set_attr as _force_set_attr
5+
46from .exceptions import InvalidSizeError
57
68__all__ = (
@@ -22,15 +24,16 @@ def move_to_mem(
2224 target : str = "memory allocation" ,
2325):
2426 """Move data to a C pointer."""
25- try :
26- if not unsafe :
27- ptr .contents [:] = stream
28- else :
29- ctypes .memmove (ptr , stream , len (stream ))
30- except ValueError as e :
27+
28+ slen = len (stream )
29+ plen = len (ptr .contents )
30+
31+ if slen > plen :
3132 raise InvalidSizeError (
32- f"object is of size { len (stream )} , while { target } is { len (ptr .contents )} " # noqa
33- ) from e
33+ f"object is of size { slen } , while { target } is { plen } " ,
34+ )
35+
36+ ctypes .memmove (ptr , stream , slen )
3437
3538
3639def attempt_decode (data : bytes ) -> Union [str , bytes ]:
@@ -78,10 +81,10 @@ def get_py(
7881 data : Type ["ctypes._CData" ],
7982) -> Type [Any ]:
8083 """Map the specified C type to a Python type."""
81- from ._pointer import BasePointer
84+ from ._pointer import BaseCPointer
8285
8386 if data .__name__ .startswith ("LP_" ):
84- return BasePointer
87+ return BaseCPointer
8588
8689 types : Dict [Type ["ctypes._CData" ], type ] = {
8790 ctypes .c_bool : bool ,
@@ -122,3 +125,19 @@ def make_py(data: "ctypes._CData"):
122125 res = attempt_decode (res )
123126
124127 return res
128+
129+
130+ def force_set_attr (typ : Type [Any ], key : str , value : Any ) -> None :
131+ """Force setting an attribute on the target type."""
132+
133+ if not isinstance (typ , type ):
134+ raise ValueError (
135+ f"{ typ } does not derive from type (did you pass an instance and not a class)?" , # noqa
136+ )
137+
138+ _force_set_attr (typ , key , value )
139+
140+
141+ def deref (address : int ) -> Any :
142+ """Get the value at the target address."""
143+ return ctypes .cast (address , ctypes .py_object ).value
0 commit comments