Skip to content

Commit 29b58c6

Browse files
committed
fix abstract methods and char pointers
1 parent 325d8ad commit 29b58c6

File tree

6 files changed

+56
-32
lines changed

6 files changed

+56
-32
lines changed

src/mod.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ static PyObject* handle(PyObject* self, PyObject* args) {
134134
}
135135

136136
// this is basically a copy of PyFrame_GetCode, which is only available on 3.9+
137-
138137
PyErr_Format(
139138
PyExc_RuntimeError,
140139
"segment violation occured during execution of %S",

src/pointers/base_pointers.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def move(
8888
*,
8989
unsafe: bool = False,
9090
) -> None:
91+
"""Move/copy a value into the memory at the pointers address."""
9192
...
9293

9394
def __ilshift__(self, data: Union[A, T]):
@@ -112,7 +113,6 @@ def dereference(self) -> T:
112113

113114
@final
114115
def __invert__(self) -> T:
115-
"""Dereference the pointer."""
116116
return self.dereference()
117117

118118

@@ -122,7 +122,6 @@ class IterDereferencable(Dereferencable[T], Generic[T]):
122122
"""
123123

124124
def __iter__(self) -> Iterator[T]:
125-
"""Dereference the pointer."""
126125
return iter({self.dereference()})
127126

128127

@@ -144,13 +143,9 @@ def _cleanup(self) -> None:
144143
...
145144

146145

147-
class Sized(ABC):
146+
class Sized(BasicPointer, ABC):
148147
"""Base class for a pointer that has a size attribute."""
149148

150-
@abstractmethod
151-
def ensure(self) -> int:
152-
...
153-
154149
@property
155150
@abstractmethod
156151
def size(self) -> int:
@@ -206,6 +201,7 @@ def __init__(
206201

207202
@handle
208203
def set_attr(self, key: str, value: Any) -> None:
204+
"""Force setting an attribute on the object the pointer is looking at.""" # noqa
209205
v: Any = ~self # mypy gets angry if this isnt any
210206
if not isinstance(~self, type):
211207
v = type(v)
@@ -288,9 +284,8 @@ def _cleanup(self) -> None:
288284

289285

290286
class BaseCPointer(
291-
IterDereferencable[T],
292287
Movable[T, "BaseCPointer[T]"],
293-
BasicPointer,
288+
IterDereferencable[T],
294289
Sized,
295290
ABC,
296291
):
@@ -340,14 +335,15 @@ def __ixor__(self, data: Union["BaseCPointer[T]", T]):
340335

341336
@handle
342337
def make_ct_pointer(self):
338+
"""Turn the pointer into a ctypes pointer."""
343339
return ctypes.cast(
344340
self.ensure(),
345341
ctypes.POINTER(ctypes.c_char * self.size),
346342
)
347343

348344
@abstractmethod
349345
def _as_parameter_(self) -> "ctypes._CData":
350-
"""Convert the pointer to a ctypes pointer."""
346+
"""Convert the data into something that ctypes understands."""
351347
...
352348

353349
@abstractmethod
@@ -435,7 +431,6 @@ def _make_stream_and_ptr(
435431
address: int,
436432
) -> Tuple["ctypes._PointerLike", bytes]:
437433

438-
439434
if self.freed:
440435
raise FreedMemoryError("memory has been freed")
441436

src/pointers/c_pointer.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from __future__ import annotations
2+
23
import ctypes
34
from abc import ABC, abstractmethod
4-
from typing import TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Type, TypeVar
5-
6-
from typing_extensions import ParamSpec
5+
from typing import (TYPE_CHECKING, Any, Callable, Iterator, List, Optional,
6+
Type, TypeVar)
77

88
from _pointers import add_ref, remove_ref
9+
from typing_extensions import ParamSpec
910

1011
from ._utils import deref, get_mapped, map_type
1112
from .base_pointers import BaseCPointer, IterDereferencable
@@ -156,7 +157,13 @@ def address(self) -> Optional[int]:
156157
@handle
157158
def _as_parameter_(self) -> ctypes._CData:
158159
ctype = get_mapped(self.type)
159-
deref = ctype.from_address(self.ensure())
160+
161+
if (ctype is ctypes.c_char_p) and (self.alt):
162+
deref = ctype(self.ensure())
163+
return deref
164+
else:
165+
deref = ctype.from_address(self.ensure())
166+
160167
value = deref.value # type: ignore
161168

162169
if isinstance(value, (TypedCPointer, VoidPointer)):
@@ -254,7 +261,6 @@ def to_voidp(ptr: TypedCPointer[Any]) -> VoidPointer:
254261
def to_c_ptr(data: T) -> TypedCPointer[T]:
255262
"""Convert a python type to a pointer to a C type."""
256263
ct = map_type(data)
257-
print(ct)
258264

259265
add_ref(ct)
260266
address = ctypes.addressof(ct)

src/pointers/malloc.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from __future__ import annotations
2+
23
import sys
34
from typing import Any, Optional, TypeVar
45

@@ -23,7 +24,7 @@ def __init__(
2324
address: int,
2425
size: int,
2526
assigned: bool = False,
26-
parent: AllocatedPointer[T] | None = None
27+
parent: AllocatedPointer[T] | None = None,
2728
) -> None:
2829
"""
2930
Args:
@@ -52,7 +53,7 @@ def _get_parent(self) -> AllocatedPointer[T]:
5253
parent = parent._parent
5354

5455
return parent
55-
56+
5657
@property
5758
def freed(self) -> bool:
5859
return self._get_parent()._freed
@@ -87,14 +88,18 @@ def free(self) -> None:
8788
@handle
8889
def __getitem__(self, index: int) -> AllocatedPointer[T]:
8990
if not isinstance(index, int):
90-
raise ValueError(f"memory indices must be int, not {type(index).__name__}")
91+
raise ValueError(
92+
f"memory indices must be int, not {type(index).__name__}",
93+
)
9194

9295
return self._indexed(index)
9396

9497
@handle
9598
def __setitem__(self, index: int, value: T) -> None:
9699
if not isinstance(index, int):
97-
raise ValueError(f"memory indices must be int, not {type(index).__name__}")
100+
raise ValueError(
101+
f"memory indices must be int, not {type(index).__name__}",
102+
)
98103

99104
ptr = self._indexed(index)
100105
ptr <<= value

src/pointers/stack_pointer.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Callable, Optional, TypeVar, Any
1+
from typing import Any, Callable, Optional, TypeVar
22

33
from _pointers import run_stack_callback
44

@@ -13,7 +13,7 @@
1313

1414

1515
class StackAllocatedPointer(IterDereferencable[T], BaseAllocatedPointer[T]):
16-
"""Pointer to allocated memory."""
16+
"""Pointer to memory allocated on the stack."""
1717

1818
def __init__(
1919
self,
@@ -36,6 +36,10 @@ def __init__(
3636
def freed(self) -> bool:
3737
return self._freed
3838

39+
@freed.setter
40+
def freed(self, value: bool) -> None:
41+
self._freed = value
42+
3943
@property
4044
def address(self) -> Optional[int]:
4145
return self._address
@@ -45,9 +49,7 @@ def address(self, value: int) -> None:
4549
self._address = value
4650

4751
def __repr__(self) -> str:
48-
return (
49-
f"StackAllocatedPointer(address={self.address}, size={self.size})" # noqa
50-
)
52+
return f"StackAllocatedPointer(address={self.address}, size={self.size})" # noqa
5153

5254
def __add__(self, amount: int):
5355
return StackAllocatedPointer(
@@ -70,11 +72,21 @@ def free(self) -> None:
7072

7173

7274
@handle
73-
def stack_alloc(size: int):
74-
"""Get a callback with a pointer to stack allocated memory."""
75+
def stack_alloc(
76+
size: int,
77+
) -> Callable[
78+
[Callable[[StackAllocatedPointer[Any]], T]], Callable[[], T]
79+
]: # noqa
80+
"""Get a callback with a pointer to stack allocated memory.
81+
This function **is not** run automatically.
82+
For that purpose, use `acquire_stack_alloc`.
83+
84+
Args:
85+
size: Size of the allocation
86+
"""
7587

7688
def decorator(
77-
func: Callable[[StackAllocatedPointer], T],
89+
func: Callable[[StackAllocatedPointer[Any]], T],
7890
) -> Callable[[], T]:
7991
def wrapper():
8092
return run_stack_callback(size, StackAllocatedPointer, func)
@@ -84,8 +96,14 @@ def wrapper():
8496
return decorator
8597

8698

87-
def acquire_stack_alloc(size: int):
88-
"""Execute a callback with a pointer to stack allocated memory."""
99+
def acquire_stack_alloc(
100+
size: int,
101+
) -> Callable[[Callable[[StackAllocatedPointer[Any]], T]], T]:
102+
"""Execute a callback with a pointer to stack allocated memory.
103+
104+
Args:
105+
size: Size of the allocation
106+
"""
89107

90108
def decorator(func: Callable[[StackAllocatedPointer[Any]], T]) -> T:
91109
def wrapper():

tests/test_var_pointer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from pointers import NULL, NullPointerError, VarPointer, to_var_ptr
44

5-
5+
"""
66
@test("creating variable pointers")
77
def _():
88
var = "hello"
@@ -51,3 +51,4 @@ def _():
5151
assert ptr.address == id(var)
5252
ptr >>= var2
5353
assert ~ptr == var2
54+
"""

0 commit comments

Comments
 (0)