Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: 
Changeset: r66261:c545818cef25
Date: 2013-08-20 15:50 +0200
http://bitbucket.org/pypy/pypy/changeset/c545818cef25/

Log:    merge

diff --git a/pypy/doc/getting-started-python.rst 
b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -57,6 +57,12 @@
      zlib-devel bzip2-devel ncurses-devel expat-devel \
      openssl-devel gc-devel python-sphinx python-greenlet
 
+   On SLES11:
+
+     $ sudo zypper install gcc make python-devel pkg-config \
+     zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
+     libexpat-devel libffi-devel python-curses
+
    The above command lines are split with continuation characters, giving the 
necessary dependencies first, then the optional ones.
 
    * ``pkg-config`` (to help us locate libffi files)
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -19,7 +19,7 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import compute_hash
+from rpython.rlib.objectmodel import compute_hash, import_from_mixin
 from rpython.rlib.rstring import StringBuilder
 
 
@@ -272,8 +272,6 @@
 # ____________________________________________________________
 
 class SubBufferMixin(object):
-    _mixin_ = True
-
     def __init__(self, buffer, offset, size):
         self.buffer = buffer
         self.offset = offset
@@ -297,10 +295,11 @@
                           # out of bounds
         return self.buffer.getslice(self.offset + start, self.offset + stop, 
step, size)
 
-class SubBuffer(SubBufferMixin, Buffer):
-    pass
+class SubBuffer(Buffer):
+    import_from_mixin(SubBufferMixin)
 
-class RWSubBuffer(SubBufferMixin, RWBuffer):
+class RWSubBuffer(RWBuffer):
+    import_from_mixin(SubBufferMixin)
 
     def setitem(self, index, char):
         self.buffer.setitem(self.offset + index, char)
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -121,7 +121,7 @@
         greens=['w_type'], reds='auto')
 
 class DescrOperation(object):
-    _mixin_ = True
+    # This is meant to be a *mixin*.
 
     def is_data_descr(space, w_obj):
         return space.lookup(w_obj, '__set__') is not None
@@ -867,12 +867,12 @@
         elif _arity == 2 and len(_specialnames) == 2:
             #print "binop", _specialnames
             _impl_maker = _make_binop_impl
-        elif _arity == 1 and len(_specialnames) == 1:
+        elif _arity == 1 and len(_specialnames) == 1 and _name != 'int':
             #print "unaryop", _specialnames
             _impl_maker = _make_unaryop_impl
         if _impl_maker:
             setattr(DescrOperation,_name,_impl_maker(_symbol,_specialnames))
-        elif _name not in ['is_', 'id','type','issubtype',
+        elif _name not in ['is_', 'id','type','issubtype', 'int',
                            # not really to be defined in DescrOperation
                            'ord', 'unichr', 'unicode']:
             raise Exception, "missing def for operation %s" % _name
diff --git a/pypy/objspace/std/builtinshortcut.py 
b/pypy/objspace/std/builtinshortcut.py
--- a/pypy/objspace/std/builtinshortcut.py
+++ b/pypy/objspace/std/builtinshortcut.py
@@ -131,6 +131,7 @@
                 w_obj = w_res
 
         # general case fallback
-        return DescrOperation.is_true(space, w_obj)
+        return _DescrOperation_is_true(space, w_obj)
 
+    _DescrOperation_is_true = DescrOperation.is_true.im_func
     space.is_true = is_true
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -10,7 +10,7 @@
 from rpython.rlib.objectmodel import instantiate, specialize, 
is_annotation_constant
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rarithmetic import base_int, widen, is_valid_int
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, import_from_mixin
 from rpython.rlib import jit
 
 # Object imports
@@ -37,9 +37,10 @@
 from pypy.objspace.std.stringtype import wrapstr
 from pypy.objspace.std.unicodetype import wrapunicode
 
-class StdObjSpace(ObjSpace, DescrOperation):
+class StdObjSpace(ObjSpace):
     """The standard object space, implementing a general-purpose object
     library in Restricted Python."""
+    import_from_mixin(DescrOperation)
 
     def initialize(self):
         "NOT_RPYTHON: only for initializing the space."
@@ -492,16 +493,19 @@
                                  self.wrap("Expected tuple of length 3"))
         return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
 
+    _DescrOperation_is_true = is_true
+    _DescrOperation_getattr = getattr
+
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
         if type(w_obj) is W_BoolObject:
             return w_obj.boolval
-        return DescrOperation.is_true(self, w_obj)
+        return self._DescrOperation_is_true(w_obj)
 
     def getattr(self, w_obj, w_name):
         if not self.config.objspace.std.getattributeshortcut:
-            return DescrOperation.getattr(self, w_obj, w_name)
+            return self._DescrOperation_getattr(w_obj, w_name)
         # an optional shortcut for performance
 
         w_type = self.type(w_obj)
diff --git a/rpython/annotator/test/test_annrpython.py 
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -2539,6 +2539,27 @@
         s = a.build_types(f, [])
         assert s.const == 2
 
+    def test_import_from_mixin(self):
+        class M(object):
+            def f(self):
+                return self.a
+        class I(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, i):
+                self.a = i
+        class S(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, s):
+                self.a = s
+        def f(n):
+            return (I(n).f(), S("a" * n).f())
+
+        assert f(3) == (3, "aaa")
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert isinstance(s.items[0], annmodel.SomeInteger)
+        assert isinstance(s.items[1], annmodel.SomeString)
+
     def test___class___attribute(self):
         class Base(object): pass
         class A(Base): pass
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -178,6 +178,17 @@
         else:
             self.emit_operation(op)
 
+    def optimize_INT_XOR(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        v2 = self.getvalue(op.getarg(1))
+
+        if v1.is_constant() and v1.box.getint() == 0:
+            self.make_equal_to(op.result, v2)
+        elif v2.is_constant() and v2.box.getint() == 0:
+            self.make_equal_to(op.result, v1)
+        else:
+            self.emit_operation(op)
+
     def optimize_FLOAT_MUL(self, op):
         arg1 = op.getarg(0)
         arg2 = op.getarg(1)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py 
b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -3263,6 +3263,20 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_fold_partially_constant_xor(self):
+        ops = """
+        [i0, i1]
+        i2 = int_xor(i0, 23)
+        i3 = int_xor(i1, 0)
+        jump(i2, i3)
+        """
+        expected = """
+        [i0, i1]
+        i2 = int_xor(i0, 23)
+        jump(i2, i1)
+        """
+        self.optimize_loop(ops, expected)
+
     # ----------
 
     def test_residual_call_does_not_invalidate_caches(self):
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -9,7 +9,7 @@
 import types
 import math
 import inspect
-from rpython.tool.sourcetools import rpython_wrapper
+from rpython.tool.sourcetools import rpython_wrapper, func_with_new_name
 
 # specialize is a decorator factory for attaching _annspecialcase_
 # attributes to functions: for example
@@ -720,3 +720,45 @@
         self.dic = dic
         self.key = key
         self.hash = hash
+
+# ____________________________________________________________
+
+def import_from_mixin(M, special_methods=['__init__', '__del__']):
+    """Copy all methods and class attributes from the class M into
+    the current scope.  Should be called when defining a class body.
+    Function and staticmethod objects are duplicated, which means
+    that annotation will not consider them as identical to another
+    copy in another unrelated class.
+    
+    By default, "special" methods and class attributes, with a name
+    like "__xxx__", are not copied unless they are "__init__" or
+    "__del__".  The list can be changed with the optional second
+    argument.
+    """
+    flatten = {}
+    for base in inspect.getmro(M):
+        if base is object:
+            continue
+        for key, value in base.__dict__.items():
+            if key.startswith('__') and key.endswith('__'):
+                if key not in special_methods:
+                    continue
+            if key in flatten:
+                continue
+            if isinstance(value, types.FunctionType):
+                value = func_with_new_name(value, value.__name__)
+            elif isinstance(value, staticmethod):
+                func = value.__get__(42)
+                func = func_with_new_name(func, func.__name__)
+                value = staticmethod(func)
+            elif isinstance(value, classmethod):
+                raise AssertionError("classmethods not supported "
+                                     "in 'import_from_mixin'")
+            flatten[key] = value
+    #
+    target = sys._getframe(1).f_locals
+    for key, value in flatten.items():
+        if key in target:
+            raise Exception("import_from_mixin: would overwrite the value "
+                            "already defined locally for %r" % (key,))
+        target[key] = value
diff --git a/rpython/rlib/rsre/rsre_char.py b/rpython/rlib/rsre/rsre_char.py
--- a/rpython/rlib/rsre/rsre_char.py
+++ b/rpython/rlib/rsre/rsre_char.py
@@ -115,10 +115,7 @@
     for function, negate in category_dispatch_unroll:
         if category_code == i:
             result = function(char_code)
-            if negate:
-                return not result # XXX this might lead to a guard
-            else:
-                return result
+            return result ^ negate
         i = i + 1
     else:
         return False
@@ -160,9 +157,7 @@
                 ppos += 1
             else:
                 return False
-    if negated:
-        return not result
-    return result
+    return result ^ negated
 
 def set_literal(pat, index, char_code):
     # <LITERAL> <code>
diff --git a/rpython/rlib/test/test_objectmodel.py 
b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -548,3 +548,76 @@
 
     r = interpret(f, [29])
     assert r == 1
+
+def test_import_from_mixin():
+    class M:    # old-style
+        def f(self): pass
+    class A:    # old-style
+        import_from_mixin(M)
+    assert A.f.im_func is not M.f.im_func
+
+    class M(object):
+        def f(self): pass
+    class A:    # old-style
+        import_from_mixin(M)
+    assert A.f.im_func is not M.f.im_func
+
+    class M:    # old-style
+        def f(self): pass
+    class A(object):
+        import_from_mixin(M)
+    assert A.f.im_func is not M.f.im_func
+
+    class M(object):
+        def f(self): pass
+    class A(object):
+        import_from_mixin(M)
+    assert A.f.im_func is not M.f.im_func
+
+    class MBase(object):
+        a = 42; b = 43; c = 1000
+        def f(self): return "hi"
+        def g(self): return self.c - 1
+    class M(MBase):
+        a = 84
+        def f(self): return "there"
+    class A(object):
+        import_from_mixin(M)
+        c = 88
+    assert A.f.im_func is not M.f.im_func
+    assert A.f.im_func is not MBase.f.im_func
+    assert A.g.im_func is not MBase.g.im_func
+    assert A().f() == "there"
+    assert A.a == 84
+    assert A.b == 43
+    assert A.c == 88
+    assert A().g() == 87
+
+    try:
+        class B(object):
+            a = 63
+            import_from_mixin(M)
+    except Exception, e:
+        assert ("would overwrite the value already defined locally for 'a'"
+                in str(e))
+    else:
+        raise AssertionError("failed to detect overwritten attribute")
+
+    class M(object):
+        def __str__(self):
+            return "m!"
+    class A(object):
+        import_from_mixin(M)
+    class B(object):
+        import_from_mixin(M, special_methods=['__str__'])
+    assert str(A()).startswith('<')
+    assert str(B()) == "m!"
+
+    class M(object):
+        pass
+    class A(object):
+        def __init__(self):
+            self.foo = 42
+    class B(A):
+        import_from_mixin(M)
+    assert B().foo == 42
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to