[pypy-commit] pypy flowoperators: Add 'pure' attribute to SpaceOperator and simplify make_op()

rlamy noreply at buildbot.pypy.org
Fri Jul 5 19:42:22 CEST 2013


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: flowoperators
Changeset: r65222:162201fa82fc
Date: 2013-05-18 22:09 +0100
http://bitbucket.org/pypy/pypy/changeset/162201fa82fc/

Log:	Add 'pure' attribute to SpaceOperator and simplify make_op()

diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -407,18 +407,9 @@
 
 def make_op(oper):
     """Add function operation to the flow space."""
-    arithmetic = False
     name = oper.name
-
-    if (name.startswith('del') or
-        name.startswith('set') or
-        name.startswith('inplace_')):
-        return make_impure_op(oper)
-    elif name in ('id', 'hash', 'iter', 'userdel'):
-        return make_impure_op(oper)
-    else:
-        func = oper.pyfunc
-        arithmetic = hasattr(operation.op, name + '_ovf')
+    func = oper.pyfunc
+    arithmetic = hasattr(operation.op, name + '_ovf')
 
     def generic_operator(self, *args_w):
         assert len(args_w) == oper.arity, name + " got the wrong number of arguments"
@@ -457,7 +448,11 @@
 
 for oper in operation.op.__dict__.values():
     if getattr(FlowObjSpace, oper.name, None) is None:
-        setattr(FlowObjSpace, oper.name, make_op(oper))
+        if oper.pure:
+            op_method = make_op(oper)
+        else:
+            op_method = make_impure_op(oper)
+        setattr(FlowObjSpace, oper.name, op_method)
 
 
 def build_flow(func, space=FlowObjSpace()):
diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py
--- a/rpython/flowspace/operation.py
+++ b/rpython/flowspace/operation.py
@@ -15,15 +15,16 @@
 func2op = {}
 
 class SpaceOperator(object):
-    def __init__(self, name, arity, symbol, pyfunc):
+    def __init__(self, name, arity, symbol, pyfunc, pure=False):
         self.name = name
         self.arity = arity
         self.symbol = symbol
         self.pyfunc = pyfunc
+        self.pure = pure
 
-def add_operator(name, arity, symbol, pyfunc=None):
+def add_operator(name, arity, symbol, pyfunc=None, pure=False):
     operator_func = getattr(operator, name, None)
-    oper = SpaceOperator(name, arity, symbol, pyfunc)
+    oper = SpaceOperator(name, arity, symbol, pyfunc, pure)
     setattr(op, name, oper)
     if pyfunc is not None:
         func2op[pyfunc] = oper
@@ -163,53 +164,53 @@
     raise ValueError("this is not supported")
 
 
-add_operator('is_', 2, 'is')
+add_operator('is_', 2, 'is', pure=True)
 add_operator('id', 1, 'id', pyfunc=id)
-add_operator('type', 1, 'type', pyfunc=new_style_type)
-add_operator('isinstance', 2, 'isinstance', pyfunc=isinstance)
-add_operator('issubtype', 2, 'issubtype', pyfunc=issubclass)  # not for old-style classes
-add_operator('repr', 1, 'repr', pyfunc=repr)
-add_operator('str', 1, 'str', pyfunc=str)
+add_operator('type', 1, 'type', pyfunc=new_style_type, pure=True)
+add_operator('isinstance', 2, 'isinstance', pyfunc=isinstance, pure=True)
+add_operator('issubtype', 2, 'issubtype', pyfunc=issubclass, pure=True)  # not for old-style classes
+add_operator('repr', 1, 'repr', pyfunc=repr, pure=True)
+add_operator('str', 1, 'str', pyfunc=str, pure=True)
 add_operator('format', 2, 'format', pyfunc=unsupported)
-add_operator('len', 1, 'len', pyfunc=len)
+add_operator('len', 1, 'len', pyfunc=len, pure=True)
 add_operator('hash', 1, 'hash', pyfunc=hash)
-add_operator('getattr', 2, 'getattr', pyfunc=getattr)
+add_operator('getattr', 2, 'getattr', pyfunc=getattr, pure=True)
 add_operator('setattr', 3, 'setattr', pyfunc=setattr)
 add_operator('delattr', 2, 'delattr', pyfunc=delattr)
-add_operator('getitem', 2, 'getitem')
+add_operator('getitem', 2, 'getitem', pure=True)
 add_operator('setitem', 3, 'setitem')
 add_operator('delitem', 2, 'delitem')
-add_operator('getslice', 3, 'getslice', pyfunc=do_getslice)
+add_operator('getslice', 3, 'getslice', pyfunc=do_getslice, pure=True)
 add_operator('setslice', 4, 'setslice', pyfunc=do_setslice)
 add_operator('delslice', 3, 'delslice', pyfunc=do_delslice)
 add_operator('trunc', 1, 'trunc', pyfunc=unsupported)
-add_operator('pos', 1, 'pos')
-add_operator('neg', 1, 'neg')
-add_operator('nonzero', 1, 'truth', pyfunc=bool)
+add_operator('pos', 1, 'pos', pure=True)
+add_operator('neg', 1, 'neg', pure=True)
+add_operator('nonzero', 1, 'truth', pyfunc=bool, pure=True)
 op.is_true = op.nonzero
-add_operator('abs' , 1, 'abs', pyfunc=abs)
-add_operator('hex', 1, 'hex', pyfunc=hex)
-add_operator('oct', 1, 'oct', pyfunc=oct)
-add_operator('ord', 1, 'ord', pyfunc=ord)
-add_operator('invert', 1, '~')
-add_operator('add', 2, '+')
-add_operator('sub', 2, '-')
-add_operator('mul', 2, '*')
-add_operator('truediv', 2, '/')
-add_operator('floordiv', 2, '//')
-add_operator('div', 2, 'div')
-add_operator('mod', 2, '%')
-add_operator('divmod', 2, 'divmod', pyfunc=divmod)
-add_operator('pow', 3, '**', pyfunc=pow)
-add_operator('lshift', 2, '<<')
-add_operator('rshift', 2, '>>')
-add_operator('and_', 2, '&')
-add_operator('or_', 2, '|')
-add_operator('xor', 2, '^')
-add_operator('int', 1, 'int', pyfunc=do_int)
-add_operator('index', 1, 'index', pyfunc=do_index)
-add_operator('float', 1, 'float', pyfunc=do_float)
-add_operator('long', 1, 'long', pyfunc=do_long)
+add_operator('abs' , 1, 'abs', pyfunc=abs, pure=True)
+add_operator('hex', 1, 'hex', pyfunc=hex, pure=True)
+add_operator('oct', 1, 'oct', pyfunc=oct, pure=True)
+add_operator('ord', 1, 'ord', pyfunc=ord, pure=True)
+add_operator('invert', 1, '~', pure=True)
+add_operator('add', 2, '+', pure=True)
+add_operator('sub', 2, '-', pure=True)
+add_operator('mul', 2, '*', pure=True)
+add_operator('truediv', 2, '/', pure=True)
+add_operator('floordiv', 2, '//', pure=True)
+add_operator('div', 2, 'div', pure=True)
+add_operator('mod', 2, '%', pure=True)
+add_operator('divmod', 2, 'divmod', pyfunc=divmod, pure=True)
+add_operator('pow', 3, '**', pyfunc=pow, pure=True)
+add_operator('lshift', 2, '<<', pure=True)
+add_operator('rshift', 2, '>>', pure=True)
+add_operator('and_', 2, '&', pure=True)
+add_operator('or_', 2, '|', pure=True)
+add_operator('xor', 2, '^', pure=True)
+add_operator('int', 1, 'int', pyfunc=do_int, pure=True)
+add_operator('index', 1, 'index', pyfunc=do_index, pure=True)
+add_operator('float', 1, 'float', pyfunc=do_float, pure=True)
+add_operator('long', 1, 'long', pyfunc=do_long, pure=True)
 add_operator('inplace_add', 2, '+=', pyfunc=inplace_add)
 add_operator('inplace_sub', 2, '-=', pyfunc=inplace_sub)
 add_operator('inplace_mul', 2, '*=', pyfunc=inplace_mul)
@@ -223,23 +224,23 @@
 add_operator('inplace_and', 2, '&=', pyfunc=inplace_and)
 add_operator('inplace_or', 2, '|=', pyfunc=inplace_or)
 add_operator('inplace_xor', 2, '^=', pyfunc=inplace_xor)
-add_operator('lt', 2, '<')
-add_operator('le', 2, '<=')
-add_operator('eq', 2, '==')
-add_operator('ne', 2, '!=')
-add_operator('gt', 2, '>')
-add_operator('ge', 2, '>=')
-add_operator('cmp', 2, 'cmp', pyfunc=cmp)   # rich cmps preferred
-add_operator('coerce', 2, 'coerce', pyfunc=coerce)
-add_operator('contains', 2, 'contains')
+add_operator('lt', 2, '<', pure=True)
+add_operator('le', 2, '<=', pure=True)
+add_operator('eq', 2, '==', pure=True)
+add_operator('ne', 2, '!=', pure=True)
+add_operator('gt', 2, '>', pure=True)
+add_operator('ge', 2, '>=', pure=True)
+add_operator('cmp', 2, 'cmp', pyfunc=cmp, pure=True)   # rich cmps preferred
+add_operator('coerce', 2, 'coerce', pyfunc=coerce, pure=True)
+add_operator('contains', 2, 'contains', pure=True)
 add_operator('iter', 1, 'iter', pyfunc=iter)
 add_operator('next', 1, 'next', pyfunc=next)
 #add_operator('call', 3, 'call')
-add_operator('get', 3, 'get', pyfunc=get)
+add_operator('get', 3, 'get', pyfunc=get, pure=True)
 add_operator('set', 3, 'set', pyfunc=set)
 add_operator('delete', 2, 'delete', pyfunc=delete)
 add_operator('userdel', 1, 'del', pyfunc=userdel)
-add_operator('buffer', 1, 'buffer', pyfunc=buffer)   # see buffer.py
+add_operator('buffer', 1, 'buffer', pyfunc=buffer, pure=True)   # see buffer.py
 
 # --- operations added by graph transformations ---
 for oper in [op.neg, op.abs, op.add, op.sub, op.mul, op.floordiv, op.div,
diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -1169,6 +1169,14 @@
                                               'iter': 1, 'newlist': 1,
                                               'next': 1, 'simple_call': 1}
 
+    def test_mutate_const_list(self):
+        lst = list('abcdef')
+        def f():
+            lst[0] = 'x'
+            return lst
+        graph = self.codetest(f)
+        assert 'setitem' in self.all_operations(graph)
+
 DATA = {'x': 5,
         'y': 6}
 


More information about the pypy-commit mailing list