Author: Armin Rigo <[email protected]>
Branch:
Changeset: r78547:2f052c461fca
Date: 2015-07-13 17:41 +0200
http://bitbucket.org/pypy/pypy/changeset/2f052c461fca/
Log: Issue #2079: missed another obscure condition in type object
creation
diff --git a/pypy/objspace/std/test/test_typeobject.py
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1031,6 +1031,48 @@
A.__dict__['x'] = 5
assert A.x == 5
+ def test_we_already_got_one_1(self):
+ # Issue #2079: highly obscure: CPython complains if we say
+ # ``__slots__="__dict__"`` and there is already a __dict__...
+ # but from the "best base" only. If the __dict__ comes from
+ # another base, it doesn't complain. Shrug and copy the logic.
+ class A(object):
+ __slots__ = ()
+ class B(object):
+ pass
+ class C(A, B): # "best base" is A
+ __slots__ = ("__dict__",)
+ class D(A, B): # "best base" is A
+ __slots__ = ("__weakref__",)
+ try:
+ class E(B, A): # "best base" is B
+ __slots__ = ("__dict__",)
+ except TypeError, e:
+ assert 'we already got one' in str(e)
+ else:
+ raise AssertionError("TypeError not raised")
+ try:
+ class F(B, A): # "best base" is B
+ __slots__ = ("__weakref__",)
+ except TypeError, e:
+ assert 'we already got one' in str(e)
+ else:
+ raise AssertionError("TypeError not raised")
+
+ def test_we_already_got_one_2(self):
+ class A(object):
+ __slots__ = ()
+ class B:
+ pass
+ class C(A, B): # "best base" is A
+ __slots__ = ("__dict__",)
+ class D(A, B): # "best base" is A
+ __slots__ = ("__weakref__",)
+ class C(B, A): # "best base" is A
+ __slots__ = ("__dict__",)
+ class D(B, A): # "best base" is A
+ __slots__ = ("__weakref__",)
+
class AppTestWithMethodCacheCounter:
spaceconfig = {"objspace.std.withmethodcachecounter": True}
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -1022,7 +1022,7 @@
w_self.nslots = w_bestbase.nslots
return hasoldstylebase
-def create_all_slots(w_self, hasoldstylebase):
+def create_all_slots(w_self, hasoldstylebase, w_bestbase):
space = w_self.space
dict_w = w_self.dict_w
if '__slots__' not in dict_w:
@@ -1040,12 +1040,12 @@
for w_slot_name in slot_names_w:
slot_name = space.str_w(w_slot_name)
if slot_name == '__dict__':
- if wantdict or w_self.hasdict:
+ if wantdict or w_bestbase.hasdict:
raise oefmt(space.w_TypeError,
"__dict__ slot disallowed: we already got one")
wantdict = True
elif slot_name == '__weakref__':
- if wantweakref or w_self.weakrefable:
+ if wantweakref or w_bestbase.weakrefable:
raise oefmt(space.w_TypeError,
"__weakref__ slot disallowed: we already got
one")
wantweakref = True
@@ -1106,7 +1106,7 @@
w_self.flag_abstract |= w_base.flag_abstract
hasoldstylebase = copy_flags_from_bases(w_self, w_bestbase)
- create_all_slots(w_self, hasoldstylebase)
+ create_all_slots(w_self, hasoldstylebase, w_bestbase)
ensure_common_attributes(w_self)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit