[pypy-commit] pypy py3.6: cpython3 compatibility for raising when calling methods on abstract classes
mattip
pypy.commits at gmail.com
Sun Aug 25 03:40:31 EDT 2019
Author: Matti Picus <matti.picus at gmail.com>
Branch: py3.6
Changeset: r97255:544f648a1d31
Date: 2019-08-25 10:36 +0300
http://bitbucket.org/pypy/pypy/changeset/544f648a1d31/
Log: cpython3 compatibility for raising when calling methods on abstract
classes
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
@@ -108,27 +108,29 @@
# array accepts very strange parameters as part of structure
# or function argument...
from ctypes import c_char, c_wchar
- if issubclass(self._type_, c_char):
- if isinstance(value, bytes):
- if len(value) > self._length_:
- raise ValueError("Invalid length")
- value = self(*value)
- elif not isinstance(value, self):
- raise TypeError("expected bytes, %s found"
- % (value.__class__.__name__,))
- elif issubclass(self._type_, c_wchar):
- if isinstance(value, str):
- if len(value) > self._length_:
- raise ValueError("Invalid length")
- value = self(*value)
- elif not isinstance(value, self):
- raise TypeError("expected unicode string, %s found"
- % (value.__class__.__name__,))
- else:
- if isinstance(value, tuple):
- if len(value) > self._length_:
- raise RuntimeError("Invalid length")
- value = self(*value)
+ if isinstance(value, self):
+ return value
+ if hasattr(self, '_type_'):
+ if issubclass(self._type_, c_char):
+ if isinstance(value, bytes):
+ if len(value) > self._length_:
+ raise ValueError("Invalid length")
+ value = self(*value)
+ elif not isinstance(value, self):
+ raise TypeError("expected bytes, %s found"
+ % (value.__class__.__name__,))
+ elif issubclass(self._type_, c_wchar):
+ if isinstance(value, str):
+ if len(value) > self._length_:
+ raise ValueError("Invalid length")
+ value = self(*value)
+ elif not isinstance(value, self):
+ raise TypeError("expected unicode string, %s found"
+ % (value.__class__.__name__,))
+ if isinstance(value, tuple):
+ if len(value) > self._length_:
+ raise RuntimeError("Invalid length")
+ value = self(*value)
return _CDataMeta.from_param(self, value)
def _build_ffiargtype(self):
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
@@ -45,6 +45,9 @@
self.details = details
class _CDataMeta(type):
+ def _is_abstract(self):
+ return getattr(self, '_type_', 'abstract') == 'abstract'
+
def from_param(self, value):
if isinstance(value, self):
return value
@@ -95,6 +98,8 @@
return self.from_address(dll.__pypy_dll__.getaddressindll(name))
def from_buffer(self, obj, offset=0):
+ if self._is_abstract():
+ raise TypeError('abstract class')
size = self._sizeofinstances()
buf = memoryview(obj)
if buf.nbytes < offset + size:
@@ -111,6 +116,8 @@
return result
def from_buffer_copy(self, obj, offset=0):
+ if self._is_abstract():
+ raise TypeError('abstract class')
size = self._sizeofinstances()
buf = memoryview(obj)
if buf.nbytes < offset + size:
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
@@ -40,14 +40,17 @@
def from_param(self, value):
if value is None:
return self(None)
- # If we expect POINTER(<type>), but receive a <type> instance, accept
- # it by calling byref(<type>).
- if isinstance(value, self._type_):
- return byref(value)
- # Array instances are also pointers when the item types are the same.
- if isinstance(value, (_Pointer, Array)):
- if issubclass(type(value)._type_, self._type_):
- return value
+ if isinstance(value, self):
+ return value
+ if hasattr(self, '_type_'):
+ # If we expect POINTER(<type>), but receive a <type> instance, accept
+ # it by calling byref(<type>).
+ if isinstance(value, self._type_):
+ return byref(value)
+ # Array instances are also pointers when the item types are the same.
+ if isinstance(value, (_Pointer, Array)):
+ if issubclass(type(value)._type_, self._type_):
+ return value
return _CDataMeta.from_param(self, value)
def _sizeofinstances(self):
@@ -60,6 +63,8 @@
return True
def set_type(self, TP):
+ if self._is_abstract():
+ raise TypeError('abstract class')
ffiarray = _rawffi.Array('P')
def __init__(self, value=None):
if not hasattr(self, '_buffer'):
@@ -179,6 +184,7 @@
klass = type(_Pointer)("LP_%s" % cls,
(_Pointer,),
{})
+ klass._type_ = 'P'
_pointer_type_cache[id(klass)] = klass
return klass
else:
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
@@ -158,6 +158,8 @@
break
else:
raise AttributeError("cannot find _type_ attribute")
+ if tp == 'abstract':
+ tp = 'i'
if (not isinstance(tp, str) or
not len(tp) == 1 or
tp not in SIMPLE_TYPE_CHARS):
@@ -341,7 +343,8 @@
def from_param(self, value):
if isinstance(value, self):
return value
-
+ if self._type_ == 'abstract':
+ raise TypeError('abstract class')
from_param_f = FROM_PARAM_BY_TYPE.get(self._type_)
if from_param_f:
res = from_param_f(self, value)
@@ -371,7 +374,7 @@
return self._type_ in "sPzUZXO"
class _SimpleCData(_CData, metaclass=SimpleType):
- _type_ = 'i'
+ _type_ = 'abstract'
def __init__(self, value=DEFAULT_VALUE):
if not hasattr(self, '_buffer'):
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
@@ -119,6 +119,8 @@
if self.is_bitfield:
# bitfield member, use direct access
return obj._buffer.__getattr__(self.name)
+ elif not isinstance(obj, _CData):
+ raise(TypeError, 'not a ctype instance')
else:
fieldtype = self.ctype
offset = self.num
@@ -142,6 +144,8 @@
from ctypes import memmove
dest = obj._buffer.fieldaddress(self.name)
memmove(dest, arg, fieldtype._fficompositesize_)
+ elif not isinstance(obj, _CData):
+ raise(TypeError, 'not a ctype instance')
else:
obj._buffer.__setattr__(self.name, arg)
@@ -209,6 +213,9 @@
__setattr__ = struct_setattr
+ def _is_abstract(self):
+ return False
+
def from_address(self, address):
instance = StructOrUnion.__new__(self)
if isinstance(address, _rawffi.StructureInstance):
More information about the pypy-commit
mailing list