[pypy-svn] r9754 - in pypy/dist/pypy: annotation objspace objspace/flow objspace/flow/test translator/test
pedronis at codespeak.net
pedronis at codespeak.net
Sun Mar 13 02:13:47 CET 2005
Author: pedronis
Date: Sun Mar 13 02:13:47 2005
New Revision: 9754
Modified:
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/objspace/dummy.py
pypy/dist/pypy/objspace/flow/objspace.py
pypy/dist/pypy/objspace/flow/test/test_objspace.py
pypy/dist/pypy/translator/test/test_annrpython.py
Log:
possible _freeze_ handling in flowspace + tests
test_circular_mutable_getattr fix
_freeze_ adaption for dummy
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Sun Mar 13 02:13:47 2005
@@ -31,6 +31,7 @@
self.cachespecializations = {}
self.pbccache = {}
self.pbctypes = {}
+ self.seen_mutable = {}
# import ordering hack
global BUILTIN_ANALYZERS
from pypy.annotation.builtin import BUILTIN_ANALYZERS
@@ -120,8 +121,12 @@
return self.getpbc(x)
else:
clsdef = self.getclassdef(x.__class__)
- for attr in x.__dict__:
- clsdef.add_source_for_attribute(attr, x)
+
+ if x not in self.seen_mutable: # avoid circular reflowing,
+ # see for example test_circular_mutable_getattr
+ for attr in x.__dict__:
+ clsdef.add_source_for_attribute(attr, x) # can trigger reflowing
+ self.seen_mutable[x] = True
return SomeInstance(clsdef)
elif x is None:
return self.getpbc(None)
Modified: pypy/dist/pypy/objspace/dummy.py
==============================================================================
--- pypy/dist/pypy/objspace/dummy.py (original)
+++ pypy/dist/pypy/objspace/dummy.py Sun Mar 13 02:13:47 2005
@@ -56,15 +56,19 @@
def __init__(self, spec):
self.spec = spec
+class BuiltinModule(Module):
+ def __init__(self, space):
+ Module.__init__(self, space, space.wrap('__builtin__'), space.wrap({}))
+ def pick_builtin(self, w_globals):
+ return self
+
class DummyObjSpace(ObjSpace):
def __init__(self):
"""NOT_RPYTHON"""
- self.builtin = Module(self, self.wrap('__builtin__'), self.wrap({}))
- def pick_builtin(w_globals):
- return self.builtin
- self.builtin.pick_builtin = pick_builtin
+ self.builtin = BuiltinModule(self)
+
self.sys = Module(self, self.wrap('sys'), self.wrap({}))
self.sys.recursionlimit = 1000
@@ -131,6 +135,8 @@
return w_obj
return w_obj.unwrap()
+ def _freeze_(self):
+ return True
if __name__ == '__main__':
dummy_space = DummyObjSpace()
Modified: pypy/dist/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/objspace.py (original)
+++ pypy/dist/pypy/objspace/flow/objspace.py Sun Mar 13 02:13:47 2005
@@ -148,6 +148,23 @@
else:
raise TypeError("not wrapped: " + repr(w_obj))
+ def unwrap_for_computation(self, w_obj):
+ obj = self.unwrap(w_obj)
+ to_check = obj
+ if hasattr(to_check, 'im_self'):
+ to_check = to_check.im_self
+ if (not isinstance(to_check, (type, types.ClassType)) and # classes/types are assumed immutable
+ hasattr(to_check, '__class__') and to_check.__class__.__module__ != '__builtin__'):
+ frozen = hasattr(to_check, '_freeze_') and to_check._freeze_()
+ if not frozen:
+ if self.concrete_mode:
+ # xxx do we want some warning? notice that some stuff is harmless
+ # like setitem(dict, 'n', mutable)
+ pass
+ else: # cannot count on it not mutating at runtime!
+ raise UnwrapException
+ return obj
+
def interpclass_w(self, w_obj):
obj = self.unwrap(w_obj)
if isinstance(obj, BaseWrappable):
@@ -248,7 +265,7 @@
def is_true(self, w_obj):
try:
- obj = self.unwrap(w_obj)
+ obj = self.unwrap_for_computation(w_obj)
except UnwrapException:
pass
else:
@@ -398,7 +415,7 @@
args = []
for w_arg in args_w:
try:
- arg = self.unwrap(w_arg)
+ arg = self.unwrap_for_computation(w_arg)
except UnwrapException:
break
else:
Modified: pypy/dist/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/test/test_objspace.py (original)
+++ pypy/dist/pypy/objspace/flow/test/test_objspace.py Sun Mar 13 02:13:47 2005
@@ -1,5 +1,5 @@
import autopath
-from pypy.objspace.flow.model import Constant, Block, traverse
+from pypy.objspace.flow.model import Constant, Block, Link, Variable, traverse
from pypy.interpreter.argument import Arguments
from pypy.translator.simplify import simplify_graph
@@ -367,6 +367,88 @@
assert op.opname != 'mul', "mul should have disappeared"
traverse(visitor, x)
+ #__________________________________________________________
+ def test_unfrozen_user_class1(self):
+ class C:
+ def __nonzero__(self):
+ return True
+ c = C()
+ def f():
+ if c:
+ return 1
+ else:
+ return 2
+ graph = self.codetest(f)
+
+ results = []
+ def visit(link):
+ if isinstance(link, Link):
+ if link.target == graph.returnblock:
+ results.extend(link.args)
+ traverse(visit, graph)
+ assert len(results) == 2
+
+ def test_unfrozen_user_class2(self):
+ class C:
+ def __add__(self, other):
+ return 4
+ c = C()
+ d = C()
+ def f():
+ return c+d
+ graph = self.codetest(f)
+
+ results = []
+ def visit(link):
+ if isinstance(link, Link):
+ if link.target == graph.returnblock:
+ results.extend(link.args)
+ traverse(visit, graph)
+ assert not isinstance(results[0], Constant)
+
+ def test_frozen_user_class1(self):
+ class C:
+ def __nonzero__(self):
+ return True
+ def _freeze_(self):
+ return True
+ c = C()
+ def f():
+ if c:
+ return 1
+ else:
+ return 2
+
+ graph = self.codetest(f)
+
+ results = []
+ def visit(link):
+ if isinstance(link, Link):
+ if link.target == graph.returnblock:
+ results.extend(link.args)
+ traverse(visit, graph)
+ assert len(results) == 1
+
+ def test_frozen_user_class2(self):
+ class C:
+ def __add__(self, other):
+ return 4
+ def _freeze_(self):
+ return True
+ c = C()
+ d = C()
+ def f():
+ return c+d
+ graph = self.codetest(f)
+
+ results = []
+ def visit(link):
+ if isinstance(link, Link):
+ if link.target == graph.returnblock:
+ results.extend(link.args)
+ traverse(visit, graph)
+ assert results == [Constant(4)]
+
DATA = {'x': 5,
'y': 6}
Modified: pypy/dist/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_annrpython.py (original)
+++ pypy/dist/pypy/translator/test/test_annrpython.py Sun Mar 13 02:13:47 2005
@@ -613,6 +613,16 @@
assert myobj.called
assert s == annmodel.SomeInstance(a.bookkeeper.getclassdef(Stuff))
+ def test_circular_mutable_getattr(self):
+ class C:
+ pass
+ c = C()
+ c.x = c
+ def f():
+ return c.x
+ a = RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.knowntype == C
def g(n):
return [0,1,2,n]
More information about the Pypy-commit
mailing list