[pypy-commit] pypy py3.5: test and fix
arigo
pypy.commits at gmail.com
Tue Jan 10 04:57:24 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r89466:9124eb47aa9d
Date: 2017-01-10 10:56 +0100
http://bitbucket.org/pypy/pypy/changeset/9124eb47aa9d/
Log: test and fix
diff --git a/pypy/objspace/std/objectobject.py b/pypy/objspace/std/objectobject.py
--- a/pypy/objspace/std/objectobject.py
+++ b/pypy/objspace/std/objectobject.py
@@ -18,25 +18,6 @@
import copyreg
return copyreg._reduce_ex(obj, proto)
-def _getnewargs(obj):
-
- try:
- getnewargs = obj.__getnewargs_ex__
- except AttributeError:
- try:
- getnewargs = obj.__getnewargs__
- except AttributeError:
- args = ()
- else:
- args = getnewargs()
- kwargs = None
- else:
- args, kwargs = getnewargs()
-
- if not isinstance(args, tuple):
- raise TypeError("__getnewargs__ should return a tuple")
- return args, kwargs
-
def _getstate(obj):
cls = obj.__class__
@@ -60,13 +41,13 @@
state = getstate()
return state
-def reduce_2(obj, proto):
+def reduce_2(obj, proto, args, kwargs):
cls = obj.__class__
import copyreg
- args, kwargs = _getnewargs(obj)
-
+ if not isinstance(args, tuple):
+ raise TypeError("__getnewargs__ should return a tuple")
if not kwargs:
newobj = copyreg.__newobj__
args2 = (cls,) + args
@@ -187,7 +168,18 @@
def descr__reduce__(space, w_obj, proto=0):
w_proto = space.wrap(proto)
if proto >= 2:
- return reduce_2(space, w_obj, w_proto)
+ w_descr = space.lookup(w_obj, '__getnewargs_ex__')
+ if w_descr is not None:
+ w_result = space.get_and_call_function(w_descr, w_obj)
+ w_args, w_kwargs = space.fixedview(w_result, 2)
+ else:
+ w_descr = space.lookup(w_obj, '__getnewargs__')
+ if w_descr is not None:
+ w_args = space.get_and_call_function(w_descr, w_obj)
+ else:
+ w_args = space.newtuple([])
+ w_kwargs = space.w_None
+ return reduce_2(space, w_obj, w_proto, w_args, w_kwargs)
return reduce_1(space, w_obj, w_proto)
@unwrap_spec(proto=int)
diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -75,6 +75,20 @@
(NamedInt, ('Name',), dict(value=42)),
dict(_name='Name'), None, None)
+ def test_reduce_ex_does_getattr(self):
+ seen = []
+ class X:
+ def __getattribute__(self, name):
+ seen.append(name)
+ return object.__getattribute__(self, name)
+ X().__reduce_ex__(2)
+ # it is the case at least on CPython 3.5.2, like PyPy:
+ assert '__reduce__' in seen
+ # but these methods, which are also called, are not looked up
+ # with getattr:
+ assert '__getnewargs__' not in seen
+ assert '__getnewargs_ex__' not in seen
+
def test_default_format(self):
class x(object):
def __str__(self):
More information about the pypy-commit
mailing list