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

pedronis at codespeak.net pedronis at codespeak.net
Sun Jun 5 00:30:27 CEST 2005


Author: pedronis
Date: Sun Jun  5 00:30:27 2005
New Revision: 13064

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/translator/test/test_annrpython.py
Log:
more fine tuning, see the new test for the point



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Sun Jun  5 00:30:27 2005
@@ -140,10 +140,10 @@
         if obj2.is_constant():
             if obj1.is_constant(): 
                 r.const = obj1.const is obj2.const
-            if obj2.const is None and not getattr(obj1, 'can_be_None', True):
+            if obj2.const is None and not obj1.can_be_none():
                 r.const = False
         elif obj1.is_constant():
-            if obj1.const is None and not getattr(obj2, 'can_be_None', True):
+            if obj1.const is None and not obj2.can_be_none():
                 r.const = False
         # XXX HACK HACK HACK
         # XXX HACK HACK HACK
@@ -151,19 +151,27 @@
         bk = getbookkeeper()
         if bk is not None: # for testing
             knowntypedata = r.knowntypedata = {}
+            fn, block, i = bk.position_key
+
+            annotator = bk.annotator
+            op = block.operations[i]
+            assert op.opname == "is_" 
+            assert len(op.args) == 2                
+
             def bind(src_obj, tgt_obj, tgt_arg):
                 if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant():
                     add_knowntypedata(knowntypedata, True, tgt_obj.is_type_of, 
                                       bk.valueoftype(src_obj.const))
 
-                fn, block, i = bk.position_key
-                annotator = bk.annotator
-                op = block.operations[i]
-                assert op.opname == "is_" 
-                assert len(op.args) == 2                
                 assert annotator.binding(op.args[tgt_arg]) == tgt_obj
                 add_knowntypedata(knowntypedata, True, [op.args[tgt_arg]], src_obj)
 
+                nonnone_obj = tgt_obj
+                if src_obj.is_constant() and src_obj.const is None and tgt_obj.can_be_none():
+                    nonnone_obj = tgt_obj.nonnoneify()
+
+                add_knowntypedata(knowntypedata, False, [op.args[tgt_arg]], nonnone_obj)
+
             bind(obj2, obj1, 0)
             bind(obj1, obj2, 1)
                 

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Sun Jun  5 00:30:27 2005
@@ -146,12 +146,19 @@
     def __setattr__(self, key, value):
         object.__setattr__(self, key, value)
 
+    def can_be_none(self):
+        return True
+        
+    def nonnoneify(self):
+        return self
 
 class SomeFloat(SomeObject):
     "Stands for a float or an integer."
     knowntype = float   # if we don't know if it's a float or an int,
                         # pretend it's a float.
 
+    def can_be_none(self):
+        return False
 
 class SomeInteger(SomeFloat):
     "Stands for an object which is known to be an integer."
@@ -169,13 +176,17 @@
     def __init__(self):
         pass
 
-
 class SomeString(SomeObject):
     "Stands for an object which is known to be a string."
     knowntype = str
     def __init__(self, can_be_None=False):
         self.can_be_None = can_be_None
 
+    def can_be_none(self):
+        return self.can_be_None
+
+    def nonnoneify(self):
+        return SomeString(can_be_None=False)
 
 class SomeChar(SomeString):
     "Stands for an object known to be a string of length 1."
@@ -184,6 +195,9 @@
     knowntype = unicode
     "Stands for an object known to be a unicode codepoint."
 
+    def can_be_none(self):
+        return False
+
 class SomeList(SomeObject):
     "Stands for a homogenous list of any length."
     knowntype = list
@@ -193,6 +207,8 @@
         return (self.__class__ is other.__class__ and
                 self.listdef.same_as(other.listdef))
 
+    def can_be_none(self):
+        return False
 
 class SomeSlice(SomeObject):
     knowntype = slice
@@ -201,6 +217,8 @@
         self.stop = stop
         self.step = step
 
+    def can_be_none(self):
+        return False
 
 class SomeTuple(SomeObject):
     "Stands for a tuple of known length."
@@ -213,6 +231,8 @@
         else:
             self.const = tuple([i.const for i in items])
 
+    def can_be_none(self):
+        return False
 
 class SomeDict(SomeObject):
     "Stands for a dict."
@@ -223,6 +243,8 @@
         return (self.__class__ is other.__class__ and
                 self.dictdef.same_as(other.dictdef))
 
+    def can_be_none(self):
+        return False
 
 class SomeIterator(SomeObject):
     "Stands for an iterator returning objects from a given container."
@@ -230,6 +252,8 @@
     def __init__(self, s_container):
         self.s_container = s_container
 
+    def can_be_none(self):
+        return False
 
 class SomeInstance(SomeObject):
     "Stands for an instance of a (user-defined) class."
@@ -242,6 +266,13 @@
     def fmt_classdef(self, cd):
         return cd.cls.__name__
 
+    def can_be_none(self):
+        return self.can_be_None
+
+    def nonnoneify(self):
+        return SomeInstance(self.classdef, can_be_None=False)
+
+
 def new_or_old_class(c):
     if hasattr(c, '__class__'):
         return c.__class__
@@ -289,6 +320,17 @@
     def isNone(self):
         return self.prebuiltinstances == {None:True}
 
+    def can_be_none(self):
+        return None in self.prebuiltinstances
+
+    def nonnoneify(self):
+        prebuiltinstances = self.prebuiltinstances.copy()
+        del prebuiltinstances[None]
+        if not prebuiltinstances:
+            return SomeImpossibleValue()
+        else:
+            return SomePBC(prebuiltinstances)
+
     def fmt_prebuiltinstances(self, pbis):
         if hasattr(self, 'const'):
             return None
@@ -310,11 +352,16 @@
         self.s_self = s_self
         self.methodname = methodname
 
+    def can_be_none(self):
+        return False
 
 class SomeImpossibleValue(SomeObject):
     """The empty set.  Instances are placeholders for objects that
     will never show up at run-time, e.g. elements of an empty list."""
 
+    def can_be_none(self):
+        return False
+
 #____________________________________________________________
 # annotation of low-level types
 
@@ -322,6 +369,8 @@
     def __init__(self, ll_ptrtype):
         self.ll_ptrtype = ll_ptrtype
 
+    def can_be_none(self):
+        return False
 
 from pypy.rpython import lltype
 

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 Jun  5 00:30:27 2005
@@ -1188,6 +1188,24 @@
         s = a.build_types(f, [int])
         assert s == a.bookkeeper.immutablevalue(None)
 
+    def test_non_None_path(self):
+        class C:
+            pass
+        def g(c):
+            if c is None:
+                return C()
+            return c
+        def f(x):
+            if x:
+                c = None
+            else:
+                c = C()
+            return g(c)
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [bool])
+        assert s.can_be_none() == False
+            
+
 def g(n):
     return [0,1,2,n]
 



More information about the Pypy-commit mailing list