diff options
author | Jens Vagelpohl <jens@plyp.com> | 2023-01-18 08:01:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-18 08:01:55 +0000 |
commit | 2a94e588ee1ef877e2e31c2897717a6662e98c0a (patch) | |
tree | 71db48a1d3e8edc23c369a871a231b27225d6581 | |
parent | f65e78d7f3a0e1f749bff67b19103051ccc8fcae (diff) | |
parent | dcde3b330f05f1b593ed191b1aadd90dceae2872 (diff) | |
download | zope-proxy-2a94e588ee1ef877e2e31c2897717a6662e98c0a.tar.gz |
Merge pull request #56 from zopefoundation/dataflake/cleanup_py2_names
Remove proxying code for names that no longer exist in Python 3
-rw-r--r-- | CHANGES.rst | 4 | ||||
-rw-r--r-- | src/zope/proxy/__init__.py | 50 | ||||
-rw-r--r-- | src/zope/proxy/_zope_proxy_proxy.c | 33 | ||||
-rw-r--r-- | src/zope/proxy/tests/test_proxy.py | 48 |
4 files changed, 50 insertions, 85 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 80c8c7d..715a970 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,10 @@ - Drop support for Python 2.7, 3.5, 3.6. +- Remove proxying code for names that no longer exist in Python 3 + like ``__long__`` and some others. + (`#55 <https://github.com/zopefoundation/zope.proxy/issues/55>`_) + 4.6.1 (2022-11-16) ================== diff --git a/src/zope/proxy/__init__.py b/src/zope/proxy/__init__.py index dfccbea..b2366ab 100644 --- a/src/zope/proxy/__init__.py +++ b/src/zope/proxy/__init__.py @@ -148,9 +148,8 @@ class AbstractPyProxyBase: def __ge__(self, other): return self._wrapped >= other - def __nonzero__(self): + def __bool__(self): return bool(self._wrapped) - __bool__ = __nonzero__ # Python3 compat def __hash__(self): return hash(self._wrapped) @@ -220,23 +219,9 @@ class AbstractPyProxyBase: def __len__(self): return len(self._wrapped) - def __getslice__(self, start, stop): - try: - getslice = type(self._wrapped).__getslice__ - except AttributeError: - return self.__getitem__(slice(start, stop)) - return getslice(self._wrapped, start, stop) - def __getitem__(self, key): return self._wrapped[key] - def __setslice__(self, start, stop, value): - try: - setslice = type(self._wrapped).__setslice__ - except AttributeError: - return self.__setitem__(slice(start, stop), value) - return setslice(self._wrapped, start, stop, value) - def __setitem__(self, key, value): self._wrapped[key] = value @@ -283,20 +268,9 @@ class AbstractPyProxyBase: def __int__(self): return int(self._wrapped) - # BBB Should go away after zope.security is fixed - # see https://github.com/zopefoundation/zope.security/issues/92 - def __long__(self): - return long(self._wrapped) # noqa: F821 undefined name - def __float__(self): return float(self._wrapped) - def __oct__(self): - return oct(self._wrapped) - - def __hex__(self): - return hex(self._wrapped) - def __index__(self): return operator.index(self._wrapped) @@ -313,12 +287,7 @@ class AbstractPyProxyBase: def __floordiv__(self, other): return self._wrapped // other - def __truediv__(self, other): # pragma: no cover - # Only one of __truediv__ and __div__ is meaningful at any one time. - return self._wrapped / other - - def __div__(self, other): # pragma: no cover - # Only one of __truediv__ and __div__ is meaningful at any one time. + def __truediv__(self, other): return self._wrapped / other def __mod__(self, other): @@ -344,12 +313,7 @@ class AbstractPyProxyBase: def __rfloordiv__(self, other): return other // self._wrapped - def __rtruediv__(self, other): # pragma: no cover - # Only one of __rtruediv__ and __rdiv__ is meaningful at any one time. - return other / self._wrapped - - def __rdiv__(self, other): # pragma: no cover - # Only one of __rtruediv__ and __rdiv__ is meaningful at any one time. + def __rtruediv__(self, other): return other / self._wrapped def __rmod__(self, other): @@ -408,13 +372,7 @@ class AbstractPyProxyBase: self._wrapped *= other return self - def __idiv__(self, other): # pragma: no cover - # Only one of __itruediv__ and __idiv__ is meaningful at any one time. - self._wrapped /= other - return self - - def __itruediv__(self, other): # pragma: no cover - # Only one of __itruediv__ and __idiv__ is meaningful at any one time. + def __itruediv__(self, other): self._wrapped /= other return self diff --git a/src/zope/proxy/_zope_proxy_proxy.c b/src/zope/proxy/_zope_proxy_proxy.c index d2cc20b..c8319aa 100644 --- a/src/zope/proxy/_zope_proxy_proxy.c +++ b/src/zope/proxy/_zope_proxy_proxy.c @@ -500,7 +500,7 @@ UNOP(index, call_index) static int -wrap_nonzero(PyObject *self) +wrap_bool(PyObject *self) { return PyObject_IsTrue(Proxy_GET_OBJECT(self)); } @@ -515,31 +515,6 @@ wrap_length(PyObject *self) return PyObject_Length(Proxy_GET_OBJECT(self)); } -static PyObject * -wrap_slice(PyObject *self, Py_ssize_t start, Py_ssize_t end) -{ - /* - * Note that we have arrived here through PySequence_GetSlice - * once already, which on Python 2 adjusted indices. We can't call - * PySequence_GetSlice again or they will be wrong. So we directly - * call the slice method the type provides. - */ - PyObject *obj = Proxy_GET_OBJECT(self); - return PySequence_GetSlice(obj, start, end); -} - -static int -wrap_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value) -{ - PyObject *obj = Proxy_GET_OBJECT(self); - if (PyList_Check(obj)) { - return PyList_SetSlice(obj, i, j, value); - } - else { - return PySequence_SetSlice(obj, i, j, value); - } -} - static int wrap_contains(PyObject *self, PyObject *value) { @@ -608,7 +583,7 @@ wrap_as_number = { wrap_neg, /* nb_negative */ wrap_pos, /* nb_positive */ wrap_abs, /* nb_absolute */ - wrap_nonzero, /* nb_nonzero */ + wrap_bool, /* nb_bool, formerly nb_nonzero */ wrap_invert, /* nb_invert */ wrap_lshift, /* nb_lshift */ wrap_rshift, /* nb_rshift */ @@ -647,9 +622,9 @@ wrap_as_sequence = { 0, /* sq_concat */ 0, /* sq_repeat */ 0, /* sq_item */ - wrap_slice, /* sq_slice */ + 0, /* sq_slice, unused in PY3 */ 0, /* sq_ass_item */ - wrap_ass_slice, /* sq_ass_slice */ + 0, /* sq_ass_slice, unused in PY3 */ wrap_contains, /* sq_contains */ }; diff --git a/src/zope/proxy/tests/test_proxy.py b/src/zope/proxy/tests/test_proxy.py index f7a7687..44082c7 100644 --- a/src/zope/proxy/tests/test_proxy.py +++ b/src/zope/proxy/tests/test_proxy.py @@ -13,8 +13,11 @@ ############################################################################## """Test base proxy class. """ +import pickle import unittest +from .. import _c_available + try: import zope.security @@ -140,6 +143,18 @@ class PyProxyBaseTestCase(unittest.TestCase): proxy = self._makeOne(_foo) self.assertEqual(str(proxy), str(_foo)) + def test__reduce__raises(self): + proxy = self._makeOne('foo') + + with self.assertRaises(pickle.PicklingError): + proxy.__reduce__() + + def test__reduce_ex__raises(self): + proxy = self._makeOne('foo') + + with self.assertRaises(pickle.PicklingError): + proxy.__reduce_ex__(0) + def test___eq___and___ne__(self): w = self._makeOne('foo') self.assertEqual(w, 'foo') @@ -191,7 +206,7 @@ class PyProxyBaseTestCase(unittest.TestCase): self.assertTrue(o2 > w1) self.assertTrue(o2 >= w2) - def test___nonzero__(self): + def test___bool__(self): w = self._makeOne(None) self.assertFalse(w) self.assertTrue(not w) @@ -310,8 +325,7 @@ class PyProxyBaseTestCase(unittest.TestCase): data = [1, 2] class DerivedList(list): - def __getslice__(self, start, stop): # pragma: no cover PY2 - return list.__getslice__(self, start, stop) + pass pList = self._makeOne(DerivedList(data)) @@ -326,9 +340,6 @@ class PyProxyBaseTestCase(unittest.TestCase): def __len__(self): return 2 - def __getslice__(self, start, end): # pragma: no cover PY2 - return (start, end) - def __getitem__(self, a_slice): # On Python 3, we basically just return what the test expects. # Mostly that's the computed indices (yay!) but there are @@ -369,8 +380,6 @@ class PyProxyBaseTestCase(unittest.TestCase): def __getitem__(self, x): raise Missing('__getitem__') - def __getslice__(self, start, stop): # pragma: no cover PY2 - raise Missing("__getslice__") target = Get() proxy = self._makeOne(target) with self.assertRaisesRegex(Missing, self.getslice): @@ -411,8 +420,6 @@ class PyProxyBaseTestCase(unittest.TestCase): def __setitem__(self, k, v): raise Missing('__setitem__') - def __setslice__(self, start, stop, value): # pragma: no cover PY2 - raise Missing("__setslice__") target = Set() proxy = self._makeOne(target) with self.assertRaisesRegex(Missing, self.setslice): @@ -739,12 +746,33 @@ class PyProxyBaseTestCase(unittest.TestCase): self.assertEqual(14, int(proxy)) +# When the C extension is not available the target class will be the same as +# the Python implementation class. No need to run tests twice in that case. +@unittest.skipUnless(_c_available, 'C extension not available') class ProxyBaseTestCase(PyProxyBaseTestCase): def _getTargetClass(self): from zope.proxy import ProxyBase return ProxyBase + def test__reduce__raises(self): + # With the C extension available the call to __reduce__ + # is delegated to copyreg._reduce_ex from the standard library. + # That function raises TypeErrors and not pickle's exceptions + proxy = self._makeOne('foo') + + with self.assertRaises(TypeError): + proxy.__reduce__() + + def test__reduce_ex__raises(self): + # With the C extension available the call to __reduce_ex__ + # is delegated to copyreg._reduce_ex from the standard library. + # That function raises TypeErrors and not pickle's exceptions + proxy = self._makeOne('foo') + + with self.assertRaises(TypeError): + proxy.__reduce_ex__(0) + class Test_py__module(unittest.TestCase): # Historically, proxying __module__ has been troublesome, |