Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r92149:90985eb27be1 Date: 2017-08-14 19:23 +0200 http://bitbucket.org/pypy/pypy/changeset/90985eb27be1/
Log: hg merge default diff --git a/pypy/module/__builtin__/descriptor.py b/pypy/module/__builtin__/descriptor.py --- a/pypy/module/__builtin__/descriptor.py +++ b/pypy/module/__builtin__/descriptor.py @@ -21,24 +21,31 @@ if space.is_none(w_obj_or_type): w_type = None # unbound super object - w_obj_or_type = space.w_None + w_obj_or_type = None else: w_type = _super_check(space, w_starttype, w_obj_or_type) self.w_starttype = w_starttype self.w_objtype = w_type - self.w_self = w_obj_or_type + self.w_self = w_obj_or_type # may be None def descr_repr(self, space): if self.w_objtype is not None: objtype_name = u"<%s object>" % self.w_objtype.getname(space) else: objtype_name = u'NULL' + if self.w_starttype is not None: + starttype_name = self.w_starttype.getname(space) + else: + starttype_name = u'NULL' return space.newunicode(u"<super: <class '%s'>, %s>" % ( - self.w_starttype.getname(space), objtype_name)) + starttype_name, objtype_name)) def get(self, space, w_obj, w_type=None): - if self.w_self is None or space.is_w(w_obj, space.w_None): + if self.w_self is not None or space.is_w(w_obj, space.w_None): return self + if self.w_starttype is None: + raise oefmt(space.w_TypeError, + "__get__(x) is invalid on an uninitialized instance of 'super'") else: # if type(self) is W_Super: # XXX write a fast path for this common case @@ -50,6 +57,7 @@ # only use a special logic for bound super objects and not for # getting the __class__ of the super object itself. if self.w_objtype is not None and name != '__class__': + assert self.w_starttype is not None w_value = space.lookup_in_type_starting_at(self.w_objtype, self.w_starttype, name) @@ -59,10 +67,9 @@ return w_value # Only pass 'obj' param if this is instance-mode super # (see CPython sourceforge id #743627) - if self.w_self is self.w_objtype: + w_obj = self.w_self + if w_obj is None or w_obj is self.w_objtype: w_obj = space.w_None - else: - w_obj = self.w_self return space.get_and_call_function(w_get, w_value, w_obj, self.w_objtype) # fallback to object.__getattribute__() @@ -160,7 +167,11 @@ _immutable_fields_ = ["w_fget", "w_fset", "w_fdel"] def __init__(self, space): - pass + self.w_fget = space.w_None + self.w_fset = space.w_None + self.w_fdel = space.w_None + self.w_doc = space.w_None + self.getter_doc = False @unwrap_spec(w_fget=WrappedDefault(None), w_fset=WrappedDefault(None), diff --git a/pypy/module/__builtin__/test/test_descriptor.py b/pypy/module/__builtin__/test/test_descriptor.py --- a/pypy/module/__builtin__/test/test_descriptor.py +++ b/pypy/module/__builtin__/test/test_descriptor.py @@ -333,6 +333,22 @@ assert repr(A()).endswith('>!') assert repr(super(A, A())) == "<super: <class 'A'>, <A object>>" + def test_super_get_corner_case(self): + class A(object): + pass + s1 = super(A, A()) + assert s1.__get__(42) is s1 + assert s1.__get__(42, int) is s1 + s2 = super(A) + assert s2.__get__(None, "anything") is s2 + # + assert s1.__get__(None, "anything") is s1 + raises(TypeError, s2.__get__, 42) + raises(TypeError, s2.__get__, 42, int) + a = A() + assert s2.__get__(a).__self__ is a + assert s1.__get__(a) is s1 + def test_property_docstring(self): assert property.__doc__.startswith('property') @@ -520,3 +536,35 @@ super() raises(RuntimeError, X().f) """ + + def test_uninitialized_property(self): + p = property.__new__(property) + raises(AttributeError, p.__get__, 42) + raises(AttributeError, p.__set__, 42, None) + raises(AttributeError, p.__delete__, 42) + assert repr(p).startswith("<property object at ") + assert p.fget is p.fset is p.fdel is p.__doc__ is None + # + lst = [] + p.deleter(lst.append).__delete__(42) + assert lst == [42] + # + lst = [] + p.getter(lst.append).__get__(43) + assert lst == [43] + # + lst = [] + p.setter(lambda x, y: lst.append((x, y))).__set__(44, 45) + assert lst == [(44, 45)] + + def test_uninitialized_super(self): + s = super.__new__(super) + assert repr(s) == "<super: <class 'NULL'>, NULL>" + assert s.__thisclass__ is s.__self__ is s.__self_class__ is None + assert s.__get__(None, "anything") is s + raises(TypeError, s.__get__, 42) + raises(TypeError, s.__get__, int) + raises(TypeError, s.__get__, type(None)) + raises(AttributeError, "s.abcde") + raises(AttributeError, "s.abcde = 42") + raises(AttributeError, "del s.abcde") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit