Author: Armin Rigo <[email protected]>
Branch:
Changeset: r53259:534c2faf1522
Date: 2012-03-07 17:07 +0000
http://bitbucket.org/pypy/pypy/changeset/534c2faf1522/
Log: merge heads
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -398,7 +398,6 @@
cls = pyobj
base = object
baselist = list(cls.__bases__)
- baselist.reverse()
# special case: skip BaseException in Python 2.5, and pretend
# that all exceptions ultimately inherit from Exception instead
@@ -408,17 +407,27 @@
elif baselist == [py.builtin.BaseException]:
baselist = [Exception]
+ mixins_before = []
+ mixins_after = []
for b1 in baselist:
if b1 is object:
continue
if b1.__dict__.get('_mixin_', False):
- self.add_mixin(b1)
+ if base is object:
+ mixins_before.append(b1)
+ else:
+ mixins_after.append(b1)
else:
assert base is object, ("multiple inheritance only
supported "
"with _mixin_: %r" % (cls,))
base = b1
+ if mixins_before and mixins_after:
+ raise Exception("unsupported: class %r has mixin bases both"
+ " before and after the regular base" % (self,))
+ self.add_mixins(mixins_after, check_not_in=base)
+ self.add_mixins(mixins_before)
+ self.add_sources_for_class(cls)
- self.add_sources_for_class(cls)
if base is not object:
self.basedesc = bookkeeper.getdesc(base)
@@ -480,14 +489,30 @@
return
self.classdict[name] = Constant(value)
- def add_mixin(self, base):
- for subbase in base.__bases__:
- if subbase is object:
- continue
- assert subbase.__dict__.get("_mixin_", False), ("Mixin class %r
has non"
- "mixin base class %r" % (base, subbase))
- self.add_mixin(subbase)
- self.add_sources_for_class(base, mixin=True)
+ def add_mixins(self, mixins, check_not_in=object):
+ if not mixins:
+ return
+ A = type('tmp', tuple(mixins) + (object,), {})
+ mro = A.__mro__
+ assert mro[0] is A and mro[-1] is object
+ mro = mro[1:-1]
+ #
+ skip = set()
+ def add(cls):
+ if cls is not object:
+ for base in cls.__bases__:
+ add(base)
+ for name in cls.__dict__:
+ skip.add(name)
+ add(check_not_in)
+ #
+ for base in reversed(mro):
+ assert base.__dict__.get("_mixin_", False), ("Mixin class %r has
non"
+ "mixin base class %r" % (mixins, base))
+ for name, value in base.__dict__.items():
+ if name in skip:
+ continue
+ self.add_source_attribute(name, value, mixin=True)
def add_sources_for_class(self, cls, mixin=False):
for name, value in cls.__dict__.items():
diff --git a/pypy/annotation/test/test_annrpython.py
b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -2431,6 +2431,52 @@
assert isinstance(s.items[1], annmodel.SomeChar)
assert isinstance(s.items[2], annmodel.SomeChar)
+ def test_mixin_first(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Base(object):
+ def foo(self): return 5
+ class Concrete(Mixin, Base):
+ pass
+ def f():
+ return Concrete().foo()
+
+ assert f() == 4
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 4
+
+ def test_mixin_last(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Base(object):
+ def foo(self): return 5
+ class Concrete(Base, Mixin):
+ pass
+ def f():
+ return Concrete().foo()
+
+ assert f() == 5
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 5
+
+ def test_mixin_concrete(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Concrete(Mixin):
+ def foo(self): return 5
+ def f():
+ return Concrete().foo()
+
+ assert f() == 5
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 5
+
def test_multiple_mixins_mro(self):
# an obscure situation, but it occurred in module/micronumpy/types.py
class A(object):
diff --git a/pypy/jit/backend/x86/codebuf.py b/pypy/jit/backend/x86/codebuf.py
--- a/pypy/jit/backend/x86/codebuf.py
+++ b/pypy/jit/backend/x86/codebuf.py
@@ -19,8 +19,8 @@
class MachineCodeBlockWrapper(BlockBuilderMixin,
- codebuilder_cls,
- LocationCodeBuilder):
+ LocationCodeBuilder,
+ codebuilder_cls):
def __init__(self):
self.init_block_builder()
# a list of relative positions; for each position p, the bytes
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit