Skip to content

Commit 3da47e2

Browse files
committed
patch null pointers
1 parent 3483bb5 commit 3da47e2

File tree

6 files changed

+54
-41
lines changed

6 files changed

+54
-41
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ classifiers = [
2323
dependencies = [
2424
"typing_extensions",
2525
]
26-
version = "2.1.0"
26+
version = "2.1.1"

src/pointers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@
2727
from .std_structs import DivT, Lconv, LDivT, Tm
2828
from .structure import Struct
2929

30-
__version__ = "2.1.0"
30+
__version__ = "2.1.1"

src/pointers/_utils.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,36 @@
1515
"make_py",
1616
)
1717

18+
_C_TYPES: Dict[type, Type["ctypes._CData"]] = {
19+
bytes: ctypes.c_char_p,
20+
str: ctypes.c_wchar_p,
21+
int: ctypes.c_int,
22+
float: ctypes.c_float,
23+
bool: ctypes.c_bool,
24+
}
25+
26+
_PY_TYPES: Dict[Type["ctypes._CData"], type] = {
27+
ctypes.c_bool: bool,
28+
ctypes.c_char: bytes,
29+
ctypes.c_wchar: str,
30+
ctypes.c_ubyte: int,
31+
ctypes.c_short: int,
32+
ctypes.c_int: int,
33+
ctypes.c_uint: int,
34+
ctypes.c_long: int,
35+
ctypes.c_ulong: int,
36+
ctypes.c_longlong: int,
37+
ctypes.c_ulonglong: int,
38+
ctypes.c_size_t: int,
39+
ctypes.c_ssize_t: int,
40+
ctypes.c_float: float,
41+
ctypes.c_double: float,
42+
ctypes.c_longdouble: float,
43+
ctypes.c_char_p: bytes,
44+
ctypes.c_wchar_p: str,
45+
ctypes.c_void_p: int,
46+
}
47+
1848

1949
def move_to_mem(
2050
ptr: "ctypes._PointerLike",
@@ -52,15 +82,7 @@ def map_type(data: Any) -> "ctypes._CData":
5282

5383
def get_mapped(typ: Any):
5484
"""Get the C mapped value of the given type."""
55-
types: Dict[type, Type["ctypes._CData"]] = {
56-
bytes: ctypes.c_char_p,
57-
str: ctypes.c_wchar_p,
58-
int: ctypes.c_int,
59-
float: ctypes.c_float,
60-
bool: ctypes.c_bool,
61-
}
62-
63-
res = types.get(typ)
85+
res = _C_TYPES.get(typ)
6486

6587
if not res:
6688
raise ValueError(f'"{typ.__name__}" is not mappable to a c type')
@@ -86,30 +108,8 @@ def get_py(
86108
if data.__name__.startswith("LP_"):
87109
return BaseCPointer
88110

89-
types: Dict[Type["ctypes._CData"], type] = {
90-
ctypes.c_bool: bool,
91-
ctypes.c_char: bytes,
92-
ctypes.c_wchar: str,
93-
ctypes.c_ubyte: int,
94-
ctypes.c_short: int,
95-
ctypes.c_int: int,
96-
ctypes.c_uint: int,
97-
ctypes.c_long: int,
98-
ctypes.c_ulong: int,
99-
ctypes.c_longlong: int,
100-
ctypes.c_ulonglong: int,
101-
ctypes.c_size_t: int,
102-
ctypes.c_ssize_t: int,
103-
ctypes.c_float: float,
104-
ctypes.c_double: float,
105-
ctypes.c_longdouble: float,
106-
ctypes.c_char_p: bytes,
107-
ctypes.c_wchar_p: str,
108-
ctypes.c_void_p: int,
109-
}
110-
111111
try:
112-
return types[data]
112+
return _PY_TYPES[data]
113113
except KeyError as e:
114114
raise ValueError(
115115
f"{data} is not a valid ctypes type",

src/pointers/base_pointers.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,11 @@ def __init__(
246246
""" # noqa
247247
self._address: Optional[int] = address
248248
self._type: Type[T] = typ
249-
obj = ~self
250249

251250
if increment_ref and address:
252-
add_ref(obj)
251+
add_ref(~self)
253252

254-
self._origin_size = sys.getsizeof(obj)
253+
self._origin_size = sys.getsizeof(~self if address else None)
255254

256255
@property
257256
def type(self):
@@ -285,12 +284,17 @@ def assign(
285284
"can only point to object pointer",
286285
)
287286

288-
if new.type is not self.type:
287+
if (new.type is not self.type) and self.address:
289288
raise TypeError(
290289
f"object at new address must be the same type (pointer looks at {self.type.__name__}, target is {new.type.__name__})", # noqa
291290
)
292291

293-
remove_ref(~self)
292+
if not self.address:
293+
self._type = new.type
294+
295+
with suppress(NullPointerError):
296+
remove_ref(~self)
297+
294298
self._address = new.address
295299
add_ref(~self)
296300

src/pointers/object_pointer.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ def move(
6363

6464
@classmethod
6565
def make_from(cls, obj: Nullable[T]) -> "Pointer[T]":
66+
is_null = obj is NULL
6667
return Pointer(
67-
id(obj) if obj is not NULL else None,
68+
id(obj) if not is_null else None,
6869
type(obj), # type: ignore
69-
True,
70+
not is_null,
7071
)
7172

7273

tests/test_pointer.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ def _():
8181
with raises(NullPointerError):
8282
print(~to_ptr(NULL))
8383

84+
ptr2 = to_ptr(NULL)
85+
ptr2 >>= 1
86+
87+
with raises(TypeError):
88+
ptr2 >>= ""
89+
90+
ptr2 >>= NULL
91+
8492

8593
@test("operator magic")
8694
def _():

0 commit comments

Comments
 (0)