Author: Alex Gaynor <[email protected]>
Branch: numpy-dtype-alt
Changeset: r46747:2acdc3b3c277
Date: 2011-08-23 12:03 -0500
http://bitbucket.org/pypy/pypy/changeset/2acdc3b3c277/

Log:    reduce code duplication in dtypes. Mixins can now have base
        classes, so long as all their complete MRO is either mixins or
        object.

diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -399,9 +399,7 @@
                 if b1 is object:
                     continue
                 if b1.__dict__.get('_mixin_', False):
-                    assert b1.__bases__ == () or b1.__bases__ == (object,), (
-                        "mixin class %r should have no base" % (b1,))
-                    self.add_sources_for_class(b1, mixin=True)
+                    self.add_mixin(b1)
                 else:
                     assert base is object, ("multiple inheritance only 
supported "
                                             "with _mixin_: %r" % (cls,))
@@ -469,6 +467,15 @@
                 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_sources_for_class(self, cls, mixin=False):
         for name, value in cls.__dict__.items():
             self.add_source_attribute(name, value, mixin)
diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -115,7 +115,10 @@
 def binop(func):
     @functools.wraps(func)
     def impl(self, v1, v2):
-        return self.adapt_val(func(self, self.unbox(v1), self.unbox(v2)))
+        return self.adapt_val(func(self,
+            self.for_computation(self.unbox(v1)),
+            self.for_computation(self.unbox(v2)),
+        ))
     return impl
 
 def unaryop(func):
@@ -124,7 +127,7 @@
         return self.box(func(self, self.unbox(v)))
     return impl
 
-class FloatArithmeticDtype(object):
+class ArithmaticTypeMixin(object):
     _mixin_ = True
 
     @binop
@@ -139,6 +142,21 @@
     @binop
     def div(self, v1, v2):
         return v1 / v2
+
+    @binop
+    def max(self, v1, v2):
+        return max(v1, v2)
+
+    def bool(self, v):
+        return bool(self.unbox(v))
+
+
+class FloatArithmeticDtype(ArithmaticTypeMixin):
+    _mixin_ = True
+
+    def for_computation(self, v):
+        return v
+
     @binop
     def mod(self, v1, v2):
         return math.fmod(v1, v2)
@@ -173,9 +191,6 @@
         return math.floor(v)
 
     @binop
-    def max(self, v1, v2):
-        return max(v1, v2)
-    @binop
     def min(self, v1, v2):
         return min(v1, v2)
     @binop
@@ -212,35 +227,16 @@
 
     def ne(self, v1, v2):
         return self.unbox(v1) != self.unbox(v2)
-    def bool(self, v):
-        return bool(self.unbox(v))
 
-class IntegerArithmeticDtype(object):
+class IntegerArithmeticDtype(ArithmaticTypeMixin):
     _mixin_ = True
 
-    # XXX: reduce the copy paste
-    @binop
-    def add(self, v1, v2):
-        return widen(v1) + widen(v2)
-    @binop
-    def sub(self, v1, v2):
-        return widen(v1) - widen(v2)
-    @binop
-    def mul(self, v1, v2):
-        return widen(v1) * widen(v2)
-    @binop
-    def div(self, v1, v2):
-        return widen(v1) / widen(v2)
+    def for_computation(self, v):
+        return widen(v)
+
     @binop
     def mod(self, v1, v2):
-        return widen(v1) % widen(v2)
-
-    @binop
-    def max(self, v1, v2):
-        return max(widen(v1), widen(v2))
-
-    def bool(self, v):
-        return bool(widen(self.unbox(v)))
+        return v1 % v2
 
     def str_format(self, item):
         return str(widen(self.unbox(item)))
@@ -260,9 +256,12 @@
         v = self.unbox(item)
         return "True" if v else "False"
 
+    def for_computation(self, v):
+        return int(v)
+
     @binop
     def add(self, v1, v2):
-        return bool(int(v1) + int(v2))
+        return bool(v1 + v2)
 
 W_Int8Dtype = create_low_level_dtype(
     num = 1, kind = SIGNEDLTR, name = "int8",
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to