[pypy-svn] r10704 - in pypy/dist/pypy: annotation translator translator/test

arigo at codespeak.net arigo at codespeak.net
Fri Apr 15 19:54:30 CEST 2005


Author: arigo
Date: Fri Apr 15 19:54:29 2005
New Revision: 10704

Added:
   pypy/dist/pypy/annotation/dictdef.py   (contents, props changed)
Removed:
   pypy/dist/pypy/annotation/factory.py
Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/listdef.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/translator/annrpython.py
   pypy/dist/pypy/translator/test/test_annrpython.py
Log:
DictDef, in the same style as ListDef.  Now factory.py is gone.



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Fri Apr 15 19:54:29 2005
@@ -9,7 +9,6 @@
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
 from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat
 from pypy.annotation.model import unionof, set, setunion, missing_operation
-from pypy.annotation.factory import generalize
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.annotation.classdef import isclassdef
 from pypy.objspace.flow.model import Constant
@@ -260,18 +259,18 @@
 class __extend__(pairtype(SomeDict, SomeDict)):
 
     def union((dic1, dic2)):
-        return SomeDict(setunion(dic1.factories, dic2.factories),
-                        unionof(dic1.s_key, dic2.s_key),
-                        unionof(dic1.s_value, dic2.s_value))
+        dic1.dictdef.merge(dic2.dictdef)
+        return dic1
 
 
 class __extend__(pairtype(SomeDict, SomeObject)):
 
     def getitem((dic1, obj2)):
-        return dic1.s_value
+        return dic1.dictdef.read_value()
 
     def setitem((dic1, obj2), s_value):
-        generalize(dic1.factories, obj2, s_value)
+        dic1.dictdef.generalize_key(obj2)
+        dic1.dictdef.generalize_value(s_value)
 
 
 class __extend__(pairtype(SomeSlice, SomeSlice)):

Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Fri Apr 15 19:54:29 2005
@@ -8,6 +8,7 @@
 from pypy.annotation.model import *
 from pypy.annotation.classdef import ClassDef
 from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
+from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
 from pypy.tool.tls import tlsobject
 from pypy.tool.hack import func_with_new_name
 from pypy.interpreter.pycode import CO_VARARGS
@@ -43,7 +44,6 @@
 
     def __init__(self, annotator):
         self.annotator = annotator
-        self.creationpoints = {} # map position-in-a-block to its Factory
         self.userclasses = {}    # map classes to ClassDefs
         self.userclasseslist = []# userclasses.keys() in creation order
         self.cachespecializations = {}
@@ -51,6 +51,7 @@
         self.pbctypes = {}
         self.seen_mutable = {}
         self.listdefs = {}       # map position_keys to ListDefs
+        self.dictdefs = {}       # map position_keys to DictDefs
         
         # mapping position -> most general result, for call sites calling
         # argtypes specialized functions
@@ -73,19 +74,6 @@
         del TLS.bookkeeper
         del self.position_key
 
-    def getfactory(self, factorycls):
-        """Get the Factory associated with the current position,
-        or build it if it doesn't exist yet."""
-        try:
-            factory = self.creationpoints[self.position_key]
-        except KeyError:
-            factory = factorycls()
-            factory.bookkeeper = self
-            factory.position_key = self.position_key
-            self.creationpoints[self.position_key] = factory
-        assert isinstance(factory, factorycls)
-        return factory
-
     def getclassdef(self, cls):
         """Get the ClassDef associated with the given user cls."""
         if cls is object:
@@ -117,6 +105,23 @@
             listdef.generalize(s_value)
         return SomeList(listdef)
 
+    def getdictdef(self):
+        """Get the DictDef associated with the current position."""
+        try:
+            dictdef = self.dictdefs[self.position_key]
+        except KeyError:
+            dictdef = self.dictdefs[self.position_key] = DictDef(self)
+        return dictdef
+
+    def newdict(self, *items_s):
+        """Make a SomeDict associated with the current position, general
+        enough to contain the given (s_key, s_value) as items."""
+        dictdef = self.getdictdef()
+        for s_key, s_value in items_s:
+            dictdef.generalize_key(s_key)
+            dictdef.generalize_value(s_value)
+        return SomeDict(dictdef)
+
 
     def immutablevalue(self, x):
         """The most precise SomeValue instance that contains the
@@ -140,7 +145,8 @@
         elif tp is dict:   # exactly a dict
             keys_s   = [self.immutablevalue(e) for e in x.keys()]
             values_s = [self.immutablevalue(e) for e in x.values()]
-            result = SomeDict({}, unionof(*keys_s), unionof(*values_s))
+            result = SomeDict(DictDef(self, unionof(*keys_s),
+                                            unionof(*values_s)))
         elif ishashable(x) and x in BUILTIN_ANALYZERS:
             result = SomeBuiltin(BUILTIN_ANALYZERS[x])
         elif callable(x) or isinstance(x, staticmethod): # XXX
@@ -216,6 +222,8 @@
             return SomeFloat()
         elif t is list:
             return SomeList(MOST_GENERAL_LISTDEF)
+        elif t is dict:
+            return SomeDict(MOST_GENERAL_DICTDEF)
         # can't do dict, tuple
         elif t.__module__ != '__builtin__':
             classdef = self.getclassdef(t)

Added: pypy/dist/pypy/annotation/dictdef.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/annotation/dictdef.py	Fri Apr 15 19:54:29 2005
@@ -0,0 +1,65 @@
+from pypy.annotation.model import SomeObject, SomeImpossibleValue, unionof
+from pypy.annotation.listdef import ListItem
+
+
+class DictKey(ListItem):
+    def patch(self):
+        for dictdef in self.itemof:
+            dictdef.dictkey = self
+
+class DictValue(ListItem):
+    def patch(self):
+        for dictdef in self.itemof:
+            dictdef.dictvalue = self
+
+
+class DictDef:
+    """A dict definition remembers how general the keys and values in that
+    particular dict have to be.  Every dict creation makes a new DictDef,
+    and the union of two dicts merges the DictKeys and DictValues that each
+    DictDef stores."""
+
+    def __init__(self, bookkeeper, s_key = SomeImpossibleValue(),
+                                 s_value = SomeImpossibleValue()):
+        self.dictkey = DictKey(bookkeeper, s_key)
+        self.dictkey.itemof[self] = True
+        self.dictvalue = DictValue(bookkeeper, s_value)
+        self.dictvalue.itemof[self] = True
+        self.bookkeeper = bookkeeper
+
+    def read_key(self, position_key=None):
+        if position_key is None:
+            if self.bookkeeper is None:   # for tests
+                from pypy.annotation.bookkeeper import getbookkeeper
+                position_key = getbookkeeper().position_key
+            else:
+                position_key = self.bookkeeper.position_key
+        self.dictkey.read_locations[position_key] = True
+        return self.dictkey.s_value
+
+    def read_value(self, position_key=None):
+        if position_key is None:
+            if self.bookkeeper is None:   # for tests
+                from pypy.annotation.bookkeeper import getbookkeeper
+                position_key = getbookkeeper().position_key
+            else:
+                position_key = self.bookkeeper.position_key
+        self.dictvalue.read_locations[position_key] = True
+        return self.dictvalue.s_value
+
+    def same_as(self, other):
+        return (self.dictkey is other.dictkey and
+                self.dictvalue is other.dictvalue)
+
+    def merge(self, other):
+        self.dictkey.merge(other.dictkey)
+        self.dictvalue.merge(other.dictvalue)
+
+    def generalize_key(self, s_key):
+        self.dictkey.generalize(s_key)
+
+    def generalize_value(self, s_value):
+        self.dictvalue.generalize(s_value)
+
+
+MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject())

Deleted: /pypy/dist/pypy/annotation/factory.py
==============================================================================
--- /pypy/dist/pypy/annotation/factory.py	Fri Apr 15 19:54:29 2005
+++ (empty file)
@@ -1,64 +0,0 @@
-"""
-Mutable Objects Factories.
-
-A factory is associated to an SpaceOperation in the source that creates a
-built-in mutable object: currently 'newlist' and 'newdict'.
-The factory remembers how general an object it has to create here.
-"""
-
-from pypy.annotation.model import SomeList, SomeDict
-from pypy.annotation.model import SomeImpossibleValue, unionof
-from pypy.annotation.bookkeeper import getbookkeeper
-
-
-
-
-##class ListFactory:
-##    s_item = SomeImpossibleValue()
-
-##    def __repr__(self):
-##        return '%s(s_item=%r)' % (self.__class__.__name__, self.s_item)
-
-##    def create(self):
-##        return SomeList(factories = {self: True}, s_item = self.s_item)
-
-##    def generalize(self, s_new_item):
-##        if not self.s_item.contains(s_new_item):
-##            self.s_item = unionof(self.s_item, s_new_item)
-##            return True
-##        else:
-##            return False
-
-
-class DictFactory:
-    s_key   = SomeImpossibleValue()
-    s_value = SomeImpossibleValue()
-
-    def __repr__(self):
-        return '%s(s_key=%r, s_value=%r)' % (self.__class__.__name__,
-                                             self.s_key, self.s_value)
-
-    def create(self):
-        return SomeDict(factories = {self: True},
-                        s_key     = self.s_key,
-                        s_value   = self.s_value)
-
-    def generalize(self, s_new_key, s_new_value):
-        if (self.s_key.contains(s_new_key) and
-            self.s_value.contains(s_new_value)):
-            return False
-        self.s_key   = unionof(self.s_key,   s_new_key)
-        self.s_value = unionof(self.s_value, s_new_value)
-        return True
-
-
-def generalize(factories, *args):
-    """Signals all the factories in the given set to generalize themselves.
-    The args must match the signature of the generalize() method of the
-    particular factories (which should all be of the same class).
-    """
-    modified = [factory for factory in factories if factory.generalize(*args)]
-    if modified:
-        for factory in modified:
-            factory.bookkeeper.annotator.reflowfromposition(factory.position_key)
-        ##raise BlockedInference   # reflow now

Modified: pypy/dist/pypy/annotation/listdef.py
==============================================================================
--- pypy/dist/pypy/annotation/listdef.py	(original)
+++ pypy/dist/pypy/annotation/listdef.py	Fri Apr 15 19:54:29 2005
@@ -10,22 +10,23 @@
         self.read_locations = {}
 
     def merge(self, other):
-        if self is other:
-            return
-        self.itemof.update(other.itemof)
-        self.read_locations.update(other.read_locations)
+        if self is not other:
+            self.itemof.update(other.itemof)
+            self.read_locations.update(other.read_locations)
+            self.patch()    # which should patch all refs to 'other'
+            self.generalize(other.s_value)
+
+    def patch(self):
         for listdef in self.itemof:
-            listdef.listitem = self   # which should patch all refs to 'other'
-        self.generalize(other.s_value)
+            listdef.listitem = self
 
     def generalize(self, s_other_value):
         s_new_value = unionof(self.s_value, s_other_value)
-        if s_new_value == self.s_value:
-            return
-        self.s_value = s_new_value
-        # reflow from all reading points
-        for position_key in self.read_locations:
-            self.bookkeeper.annotator.reflowfromposition(position_key)
+        if s_new_value != self.s_value:
+            self.s_value = s_new_value
+            # reflow from all reading points
+            for position_key in self.read_locations:
+                self.bookkeeper.annotator.reflowfromposition(position_key)
 
 
 class ListDef:

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Fri Apr 15 19:54:29 2005
@@ -132,7 +132,6 @@
     "Stands for a homogenous list of any length."
     knowntype = list
     def __init__(self, listdef):
-        assert hasattr(listdef, 'listitem')   # XXX remove me
         self.listdef = listdef
     def __eq__(self, other):
         return (self.__class__ is other.__class__ and
@@ -162,10 +161,11 @@
 class SomeDict(SomeObject):
     "Stands for a dict."
     knowntype = dict
-    def __init__(self, factories, s_key, s_value):
-        self.factories = factories
-        self.s_key = s_key
-        self.s_value = s_value
+    def __init__(self, dictdef):
+        self.dictdef = dictdef
+    def __eq__(self, other):
+        return (self.__class__ is other.__class__ and
+                self.dictdef.same_as(other.dictdef))
 
 
 class SomeIterator(SomeObject):

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Fri Apr 15 19:54:29 2005
@@ -11,7 +11,6 @@
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeFloat
 from pypy.annotation.model import SomeIterator, SomePBC, new_or_old_class
 from pypy.annotation.model import unionof, set, setunion, missing_operation
-from pypy.annotation.factory import generalize
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.annotation.classdef import isclassdef
 from pypy.annotation import builtin
@@ -201,22 +200,24 @@
 
 class __extend__(SomeDict):
     def iter(dct):
-        return SomeIterator(dct.s_key)
+        return SomeIterator(dct.dictdef.read_key())
 
     def method_copy(dct):
-        return SomeDict(dct.factories, dct.s_key, dct.s_value)
+        return dct
 
     def method_update(dct1, dct2):
-        generalize(dct1.factories, dct2.s_key, dct2.s_value)
+        dct1.dictdef.generalize_key(dct2.dictdef.read_key())
+        dct1.dictdef.generalize_value(dct2.dictdef.read_value())
 
     def method_keys(dct):
-        return getbookkeeper().newlist(dct.s_key)
+        return getbookkeeper().newlist(dct.dictdef.read_key())
 
     def method_values(dct):
-        return getbookkeeper().newlist(dct.s_value)
+        return getbookkeeper().newlist(dct.dictdef.read_value())
 
     def method_items(dct):
-        return getbookkeeper().newlist(SomeTuple((dct.s_key, dct.s_value)))
+        return getbookkeeper().newlist(SomeTuple((dct.dictdef.read_key(),
+                                                  dct.dictdef.read_value())))
         
 
 class __extend__(SomeString):

Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py	(original)
+++ pypy/dist/pypy/translator/annrpython.py	Fri Apr 15 19:54:29 2005
@@ -4,7 +4,6 @@
 from pypy.tool.ansi_print import ansi_print
 from pypy.annotation import model as annmodel
 from pypy.annotation.model import pair
-from pypy.annotation.factory import DictFactory
 from pypy.annotation.bookkeeper import Bookkeeper
 from pypy.objspace.flow.model import Variable, Constant, undefined_value
 from pypy.objspace.flow.model import SpaceOperation, FunctionGraph
@@ -482,9 +481,11 @@
         return self.bookkeeper.newlist(*args)
 
     def consider_op_newdict(self, *args):
-        assert not args, "XXX only supports newdict([])"
-        factory = self.bookkeeper.getfactory(DictFactory)
-        return factory.create()
+        assert len(args) % 2 == 0
+        items_s = []
+        for i in range(0, len(args), 2):
+            items_s.append((args[i], args[i+1]))
+        return self.bookkeeper.newdict(*items_s)
 
     def consider_op_newslice(self, start, stop, step):
         return annmodel.SomeSlice(start, stop, step)

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	Fri Apr 15 19:54:29 2005
@@ -6,6 +6,7 @@
 from pypy.translator.annrpython import RPythonAnnotator, annmodel
 from pypy.translator.translator import Translator
 from pypy.annotation.listdef import ListDef
+from pypy.annotation.dictdef import DictDef
 from pypy.objspace.flow.model import *
 from pypy.tool.rarithmetic import r_uint
 
@@ -18,6 +19,17 @@
 def somelist(s_type=annmodel.SomeObject()):
     return annmodel.SomeList(ListDef(None, s_type))
 
+def dictkey(s_dict):
+    assert isinstance(s_dict, annmodel.SomeDict)
+    return s_dict.dictdef.dictkey.s_value
+
+def dictvalue(s_dict):
+    assert isinstance(s_dict, annmodel.SomeDict)
+    return s_dict.dictdef.dictvalue.s_value
+
+def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()):
+    return annmodel.SomeDict(DictDef(None, s_key, s_value))
+
 
 class TestAnnonateTestCase:
     objspacename = 'flow'
@@ -410,7 +422,7 @@
         
     def test_simple_iter_dict(self):
         a = RPythonAnnotator()
-        t = annmodel.SomeDict({}, annmodel.SomeInteger(), annmodel.SomeInteger())
+        t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
         s = a.build_types(snippet.simple_iter, [t])
         assert isinstance(s, annmodel.SomeIterator)
 
@@ -426,24 +438,21 @@
         
     def test_dict_copy(self):
         a = RPythonAnnotator()
-        t = annmodel.SomeDict({}, annmodel.SomeInteger(), annmodel.SomeInteger())
+        t = somedict(annmodel.SomeInteger(), annmodel.SomeInteger())
         s = a.build_types(snippet.dict_copy, [t])
-        assert isinstance(s, annmodel.SomeDict)
-        assert isinstance(s.s_key, annmodel.SomeInteger)
-        assert isinstance(s.s_value, annmodel.SomeInteger)
+        assert isinstance(dictkey(s), annmodel.SomeInteger)
+        assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
     def test_dict_update(self):
         a = RPythonAnnotator()
         s = a.build_types(snippet.dict_update, [int])
-        assert isinstance(s, annmodel.SomeDict)
-        assert isinstance(s.s_key, annmodel.SomeInteger)
-        assert isinstance(s.s_value, annmodel.SomeInteger)
+        assert isinstance(dictkey(s), annmodel.SomeInteger)
+        assert isinstance(dictvalue(s), annmodel.SomeInteger)
 
         a = RPythonAnnotator()
         s = a.build_types(snippet.dict_update, [str])
-        assert isinstance(s, annmodel.SomeDict)
-        assert not isinstance(s.s_key, annmodel.SomeString)
-        assert not isinstance(s.s_value, annmodel.SomeString)
+        assert not isinstance(dictkey(s), annmodel.SomeString)
+        assert not isinstance(dictvalue(s), annmodel.SomeString)
 
     def test_dict_keys(self):
         a = RPythonAnnotator()



More information about the Pypy-commit mailing list