Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit