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