[pypy-svn] r78958 - in pypy/branch/rlist-jit/pypy/annotation: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Nov 10 13:24:57 CET 2010
Author: arigo
Date: Wed Nov 10 13:24:55 2010
New Revision: 78958
Modified:
pypy/branch/rlist-jit/pypy/annotation/description.py
pypy/branch/rlist-jit/pypy/annotation/listdef.py
pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py
Log:
* Merge r78957 from branch/fast-forward.
* Mark the 'x.list' marked as _immutable_fields_=['list[*]']
with never_mutate(), to make sure.
Modified: pypy/branch/rlist-jit/pypy/annotation/description.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/description.py (original)
+++ pypy/branch/rlist-jit/pypy/annotation/description.py Wed Nov 10 13:24:55 2010
@@ -647,7 +647,9 @@
while cdesc is not None:
if '_immutable_fields_' in cdesc.classdict:
if search in cdesc.classdict['_immutable_fields_'].value:
- return s_result.listdef.offspring()
+ s_copy = s_result.listdef.offspring()
+ s_copy.listdef.never_mutate()
+ return s_copy
cdesc = cdesc.basedesc
return s_result # common case
Modified: pypy/branch/rlist-jit/pypy/annotation/listdef.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/listdef.py (original)
+++ pypy/branch/rlist-jit/pypy/annotation/listdef.py Wed Nov 10 13:24:55 2010
@@ -6,11 +6,16 @@
class TooLateForChange(Exception):
pass
+class ListChangeUnallowed(Exception):
+ pass
+
class ListItem(object):
mutated = False # True for lists mutated after creation
resized = False # True for lists resized after creation
range_step = None # the step -- only for lists only created by a range()
dont_change_any_more = False # set to True when too late for changes
+ must_not_mutate = False # make_sure_not_modified()
+ must_not_resize = False # make_sure_not_resized()
# what to do if range_step is different in merge.
# - if one is a list (range_step is None), unify to a list.
@@ -26,7 +31,6 @@
self.bookkeeper = bookkeeper
self.itemof = {} # set of all ListDefs using this ListItem
self.read_locations = {}
- self.dont_resize = False
if bookkeeper is None:
self.dont_change_any_more = True
@@ -34,12 +38,16 @@
if not self.mutated:
if self.dont_change_any_more:
raise TooLateForChange
+ if self.must_not_mutate:
+ raise ListChangeUnallowed("mutating list")
self.mutated = True
def resize(self):
if not self.resized:
- if self.dont_change_any_more or self.dont_resize:
+ if self.dont_change_any_more:
raise TooLateForChange
+ if self.must_not_resize:
+ raise ListChangeUnallowed("resizing list")
self.resized = True
def setrangestep(self, step):
@@ -63,11 +71,16 @@
# things more general
self, other = other, self
- if other.dont_resize:
- if self.resized:
- raise TooLateForChange()
- self.dont_resize = True
- if other.mutated: self.mutate()
+ if other.must_not_mutate:
+ if self.mutated:
+ raise ListChangeUnallowed("list merge with a mutated")
+ self.must_not_mutate = True
+ if other.must_not_resize:
+ if self.resized:
+ raise ListChangeUnallowed("list merge with a resized")
+ self.must_not_resize = True
+ if other.mutated:
+ self.mutate()
if other.resized:
self.resize()
if other.range_step != self.range_step:
@@ -189,13 +202,14 @@
def never_resize(self):
if self.listitem.resized:
- raise TooLateForChange()
- self.listitem.dont_resize = True
+ raise ListChangeUnallowed("list already resized")
+ self.listitem.must_not_resize = True
def never_mutate(self):
- if self.listitem.resized or self.listitem.mutated:
- raise TooLateForChange()
- self.listitem.dont_change_any_more = True
+ self.never_resize()
+ if self.listitem.mutated:
+ raise ListChangeUnallowed("list already mutated")
+ self.listitem.must_not_mutate = True
MOST_GENERAL_LISTDEF = ListDef(None, SomeObject())
Modified: pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py Wed Nov 10 13:24:55 2010
@@ -10,7 +10,7 @@
from pypy.translator.translator import graphof as tgraphof
from pypy.annotation import policy
from pypy.annotation import specialize
-from pypy.annotation.listdef import ListDef, TooLateForChange
+from pypy.annotation.listdef import ListDef, ListChangeUnallowed
from pypy.annotation.dictdef import DictDef
from pypy.objspace.flow.model import *
from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong
@@ -3206,7 +3206,7 @@
l.append(4)
a = self.RPythonAnnotator()
- py.test.raises(TooLateForChange, a.build_types, g, [])
+ py.test.raises(ListChangeUnallowed, a.build_types, g, [])
assert called
def test_listitem_no_mutating2(self):
@@ -3229,7 +3229,7 @@
a = self.RPythonAnnotator()
a.translator.config.translation.list_comprehension_operations = True
- py.test.raises(TooLateForChange, a.build_types, fn, [int])
+ py.test.raises(ListChangeUnallowed, a.build_types, fn, [int])
def test_listitem_never_resize(self):
from pypy.rlib.debug import check_annotation
@@ -3243,7 +3243,7 @@
check_annotation(l, checker)
a = self.RPythonAnnotator()
- py.test.raises(TooLateForChange, a.build_types, f, [])
+ py.test.raises(ListChangeUnallowed, a.build_types, f, [])
def test_len_of_empty_list(self):
@@ -3357,6 +3357,38 @@
# not a constant: both __enter__ and __exit__ have been annotated
assert not s.is_constant()
+ def test_make_sure_not_modified(self):
+ from pypy.rlib.debug import make_sure_not_modified
+
+ def pycode(consts):
+ make_sure_not_modified(consts)
+ def build1():
+ return pycode(consts=[1])
+ def build2():
+ return pycode(consts=[0])
+ def fn():
+ build1()
+ build2()
+
+ a = self.RPythonAnnotator()
+ a.translator.config.translation.list_comprehension_operations = True
+ a.build_types(fn, [])
+ # assert did not raise ListChangeUnallowed
+
+ def test_return_immutable_list(self):
+ class A:
+ _immutable_fields_ = 'lst[*]'
+ def f(n):
+ a = A()
+ l1 = [n]
+ l1.append(n+1)
+ a.lst = l1
+ return a.lst
+
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [int])
+ assert s.listdef.listitem.must_not_mutate
+
def g(n):
return [0,1,2,n]
More information about the Pypy-commit
mailing list