[pypy-svn] r9603 - in pypy/dist/pypy: annotation translator/test
pedronis at codespeak.net
pedronis at codespeak.net
Thu Mar 3 16:52:33 CET 2005
Author: pedronis
Date: Thu Mar 3 16:52:33 2005
New Revision: 9603
Modified:
pypy/dist/pypy/annotation/classdef.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/translator/test/snippet.py
pypy/dist/pypy/translator/test/test_annrpython.py
Log:
use structural comparison to decide when not to bump rev numbers.
Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py (original)
+++ pypy/dist/pypy/annotation/classdef.py Thu Mar 3 16:52:33 2005
@@ -6,6 +6,7 @@
from types import FunctionType
from pypy.annotation.model import SomeImpossibleValue, unionof, RevDiff
+notyet = object()
class Attribute:
# readonly-ness
@@ -20,8 +21,11 @@
self.s_value = SomeImpossibleValue()
self.readonly = True
+ self.flat = notyet
+
def getvalue(self):
while self.sources:
+ self.flat = notyet
source, classdef = self.sources.popitem()
s_value = self.bookkeeper.immutablevalue(
source.__dict__[self.name])
@@ -35,6 +39,13 @@
self.sources.update(other.sources)
self.s_value = unionof(self.s_value, other.s_value)
self.readonly = self.readonly and other.readonly
+ self.flat = notyet
+
+ def structure(self):
+ s_value = self.getvalue()
+ if self.flat is notyet:
+ self.flat = s_value.structure()
+ return self.flat
class ClassDef:
@@ -125,13 +136,19 @@
del subdef.attrs[attr]
bump = True
+ attach_flat = None
# don't bump if the only cause is rev diff discrepancies
if was_here and len(subclass_attrs) == 1 and s_value is not None:
old_attr = subclass_attrs[0]
wasgeneralenough = old_attr.s_value.contains(s_value)
assert not wasgeneralenough
if wasgeneralenough is RevDiff:
- bump = False
+ s_value_struct = s_value.structure()
+ if not old_attr.flat is notyet:
+ old_attr_struct = old_attr.structure()
+ if s_value_struct == old_attr_struct:
+ bump = False
+ attach_flat = s_value_struct
if bump:
# bump the revision number of this class and all subclasses
@@ -147,6 +164,9 @@
newattr.merge(subattr)
self.attrs[attr] = newattr
+ if attach_flat is not None:
+ newattr.flat = attach_flat
+
# reflow from all factories
for position in self.getallinstantiations():
self.bookkeeper.annotator.reflowfromposition(position)
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Thu Mar 3 16:52:33 2005
@@ -134,6 +134,23 @@
del set_caused_by_merge
+ # structural expansion
+
+ def structure(self, memo=None):
+ if self.is_constant():
+ return self.const
+ if memo is None:
+ memo = {}
+ return self._structure(memo)
+
+ def _structure(self, memo):
+ return self
+
+class struct(tuple):
+ def __new__(cls, *args):
+ return tuple.__new__(cls,args)
+
+
class SomeInteger(SomeObject):
"Stands for an object which is known to be an integer."
knowntype = int
@@ -170,6 +187,9 @@
def hom_contains(self, other):
return self.s_item.contains(other.s_item)
+ def _structure(self, memo):
+ return struct(list, self.s_item.structure(memo))
+
class SomeSlice(SomeObject):
knowntype = slice
@@ -183,6 +203,14 @@
self.stop.contains(other.stop),
self.step.contains(other.step))
+ def _structure(self, memo):
+ return struct(slice,
+ self.start.structure(memo),
+ self.stop.structure(memo),
+ self.step.structure(memo),
+ )
+
+
class SomeTuple(SomeObject):
"Stands for a tuple of known length."
@@ -202,6 +230,10 @@
return False
return contains_and(*[i1.contains(i2) for i1,i2 in zip(self_items, other_items)])
+ def _structure(self, memo):
+ return struct(tuple,*[ i.structure(memo) for i in self.items])
+
+
class SomeDict(SomeObject):
"Stands for a dict."
@@ -216,6 +248,12 @@
self.s_value.contains(other.s_value))
+ def _structure(self, memo):
+ return struct(dict,
+ self.s_key.structure(memo),
+ self.s_value.structure(memo))
+
+
class SomeIterator(SomeObject):
"Stands for an iterator returning objects of a known type."
knowntype = type(iter([])) # arbitrarily chose seqiter as the type
@@ -225,6 +263,10 @@
def hom_contains(self, other):
return self.s_item.contains(other.s_item)
+ def _structure(self, memo):
+ return struct(iter,
+ self.s_item.structure(memo))
+
class SomeInstance(SomeObject):
"Stands for an instance of a (user-defined) class."
def __init__(self, classdef):
@@ -244,6 +286,27 @@
return RevDiff
return self.classdef.commonbase(other.classdef) is self.classdef
+ def _classdef_structure(self, classdef, memo):
+ if classdef is None:
+ return None
+ if classdef in memo or classdef.cls.__module__ == '__builtin__':
+ return struct(classdef)
+ attr_names = classdef.attrs.keys()
+ attr_names.sort()
+ attrs = classdef.attrs
+ parts = [classdef]
+ memo[classdef] = None
+ parts.append(self._classdef_structure(classdef.basedef, memo))
+ for name in attr_names:
+ a = attrs[name]
+ parts.append((name, a.getvalue().structure(memo)))
+ strct = struct(*parts)
+ return strct
+
+ def _structure(self, memo): # xxx try later an approach that can cache classef expansions
+ return self._classdef_structure(self.classdef, memo)
+
+
def new_or_old_class(c):
if hasattr(c, '__class__'):
return c.__class__
@@ -314,6 +377,15 @@
return other.s_self is None
return self.s_self.contains(other.s_self)
+ def _structure(self, memo):
+ if self.s_self:
+ return struct(len,
+ self.analyser,
+ self.s_self.structure(memo))
+ else:
+ return struct(len,
+ self.analyser)
+
class SomeImpossibleValue(SomeObject):
"""The empty set. Instances are placeholders for objects that
Modified: pypy/dist/pypy/translator/test/snippet.py
==============================================================================
--- pypy/dist/pypy/translator/test/snippet.py (original)
+++ pypy/dist/pypy/translator/test/snippet.py Thu Mar 3 16:52:33 2005
@@ -956,3 +956,32 @@
return Odd(n)
+# shows that we care about the expanded structure in front of changes to attributes involving only
+# instances rev numbers
+
+class Box:
+ pass
+
+class Box2:
+ pass
+
+class Box3(Box2):
+ pass
+
+def flow_rev_numbers(n):
+ bx3 = Box3()
+ bx3.x = 1
+ bx = Box()
+ bx.bx3 = bx3
+ if n >0:
+ z = bx.bx3.x
+ if n >0:
+ bx2 = Box2()
+ bx2.x = 3
+ return z
+ raise Exception
+
+
+
+
+
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 Thu Mar 3 16:52:33 2005
@@ -552,6 +552,11 @@
assert Odd_def.attrs['x'].s_value.s_item.knowntype == snippet.Even
assert Odd_def.attrs['y'].s_value.s_item.knowntype == snippet.Odd
+ def test_flow_rev_numbers(self):
+ a = RPythonAnnotator()
+ s = a.build_types(snippet.flow_rev_numbers, [])
+ assert s.knowntype == int
+ assert not s.is_constant() # !
def g(n):
More information about the Pypy-commit
mailing list