Author: Armin Rigo <[email protected]>
Branch:
Changeset: r95051:7756ae58c273
Date: 2018-08-31 09:26 +0200
http://bitbucket.org/pypy/pypy/changeset/7756ae58c273/
Log: Issue #2879
another ctypes fix
diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -183,6 +183,7 @@
self._buffer = self._ffiarray(self._length_, autofree=True)
for i, arg in enumerate(args):
self[i] = arg
+ _init_no_arg_ = __init__
def _fix_index(self, index):
if index < 0:
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -120,7 +120,7 @@
raise ValueError(
"Buffer size too small (%d instead of at least %d bytes)"
% (len(buf) + offset, size + offset))
- result = self()
+ result = self._newowninstance_()
dest = result._buffer.buffer
try:
raw_addr = buf._pypy_raw_address()
@@ -131,6 +131,11 @@
memmove(dest, raw_addr, size)
return result
+ def _newowninstance_(self):
+ result = self.__new__(self)
+ result._init_no_arg_()
+ return result
+
class CArgObject(object):
""" simple wrapper around buffer, just for the case of freeing
@@ -162,6 +167,7 @@
def __init__(self, *args, **kwds):
raise TypeError("%s has no type" % (type(self),))
+ _init_no_arg_ = __init__
def _ensure_objects(self):
if '_objects' not in self.__dict__:
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -268,6 +268,7 @@
return
raise TypeError("Unknown constructor %s" % (args,))
+ _init_no_arg_ = __init__
def _wrap_callable(self, to_call, argtypes):
def f(*args):
@@ -557,7 +558,7 @@
keepalive, newarg, newargtype =
self._conv_param(argtype, defval)
else:
import ctypes
- val = argtype._type_()
+ val = argtype._type_._newowninstance_()
keepalive = None
newarg = ctypes.byref(val)
newargtype = type(newarg)
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -67,8 +67,11 @@
self._buffer = ffiarray(1, autofree=True)
if value is not None:
self.contents = value
+ def _init_no_arg_(self):
+ self._buffer = ffiarray(1, autofree=True)
self._ffiarray = ffiarray
self.__init__ = __init__
+ self._init_no_arg_ = _init_no_arg_
self._type_ = TP
def _build_ffiargtype(self):
@@ -137,27 +140,21 @@
if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
raise TypeError("cast() argument 2 must be a pointer type, not %s"
% (tp,))
+ result = tp._newowninstance_()
if isinstance(obj, (int, long)):
- result = tp()
result._buffer[0] = obj
return result
elif obj is None:
- result = tp()
return result
elif isinstance(obj, Array):
- ptr = tp.__new__(tp)
- ptr._buffer = tp._ffiarray(1, autofree=True)
- ptr._buffer[0] = obj._buffer
- result = ptr
+ result._buffer[0] = obj._buffer
elif isinstance(obj, bytes):
- result = tp()
result._buffer[0] = buffer(obj)._pypy_raw_address()
return result
elif not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
raise TypeError("cast() argument 1 must be a pointer, not %s"
% (type(obj),))
else:
- result = tp()
result._buffer[0] = obj._buffer[0]
# The casted objects '_objects' member:
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -390,6 +390,7 @@
self._buffer = self._ffiarray(1, autofree=True)
if value is not DEFAULT_VALUE:
self.value = value
+ _init_no_arg_ = __init__
def _ensure_objects(self):
if self._type_ not in 'zZP':
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -281,6 +281,7 @@
self.__setattr__(name, arg)
for name, arg in kwds.items():
self.__setattr__(name, arg)
+ _init_no_arg_ = __init__
def _subarray(self, fieldtype, name):
"""Return a _rawffi array of length 1 whose address is the same as
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
@@ -503,6 +503,22 @@
assert dostruct(Native) == dostruct(Big)
assert dostruct(Native) != dostruct(Little)
+ def test_from_buffer_copy(self):
+ from array import array
+
+ class S(Structure):
+ _fields_ = [('i', c_int)]
+ def __init__(self, some, unused, arguments):
+ pass
+ a = array('i', [1234567])
+ s1 = S.from_buffer(a)
+ s2 = S.from_buffer_copy(a)
+ assert s1.i == 1234567
+ assert s2.i == 1234567
+ a[0] = -7654321
+ assert s1.i == -7654321
+ assert s2.i == 1234567
+
class TestPointerMember(BaseCTypesTestChecker):
def test_1(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit