Author: Ronan Lamy <[email protected]>
Branch: anntype
Changeset: r80781:7d8c6879587b
Date: 2015-11-19 16:50 +0000
http://bitbucket.org/pypy/pypy/changeset/7d8c6879587b/

Log:    Implement unions of SomeException with SomeInstance

diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -492,21 +492,21 @@
             if can_only_throw is not None:
                 # filter out those exceptions which cannot
                 # occur for this specific, typed operation.
-                candidates = can_only_throw
-                s_exception = SomeException(set(can_only_throw))
+                s_exception = self.bookkeeper.new_exception(can_only_throw)
                 for link in exits:
                     case = link.exitcase
-                    s_case = SomeExceptCase(case)
                     if case is None:
                         self.follow_link(graph, link, {})
                         continue
                     if s_exception == s_ImpossibleValue:
                         break
+                    s_case = SomeExceptCase(
+                            self.bookkeeper.getuniqueclassdef(case))
                     s_matching_exc = s_exception.intersection(s_case)
                     if s_matching_exc != s_ImpossibleValue:
                         self.follow_raise_link(graph, link,
                             constraints={link.last_exc_value:
-                                
s_matching_exc.as_SomeInstance(self.bookkeeper)})
+                                s_matching_exc.as_SomeInstance()})
                     s_exception = s_exception.difference(s_case)
             else:
                 for link in exits:
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -6,14 +6,14 @@
 from rpython.tool.pairtype import pair, pairtype
 from rpython.annotator.model import (
     SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList,
-    SomeDict, SomeUnicodeCodePoint, SomeUnicodeString,
+    SomeDict, SomeUnicodeCodePoint, SomeUnicodeString, SomeException,
     SomeTuple, SomeImpossibleValue, s_ImpossibleValue, SomeInstance,
     SomeBuiltinMethod, SomeIterator, SomePBC, SomeNone, SomeFloat, s_None,
     SomeByteArray, SomeWeakRef, SomeSingleFloat,
     SomeLongFloat, SomeType, SomeTypeOf, SomeConstantType, unionof, UnionError,
     read_can_only_throw, add_knowntypedata,
     merge_knowntypedata,)
-from rpython.annotator.bookkeeper import immutablevalue
+from rpython.annotator.bookkeeper import immutablevalue, getbookkeeper
 from rpython.flowspace.model import Variable, Constant, const
 from rpython.flowspace.operation import op
 from rpython.rlib import rarithmetic
@@ -677,6 +677,14 @@
             thistype = pairtype(SomeInstance, SomeInstance)
             return super(thistype, pair(ins1, ins2)).improve()
 
+class __extend__(pairtype(SomeException, SomeInstance)):
+    def union((s_exc, s_inst)):
+        return unionof(s_exc.as_SomeInstance(), s_inst)
+
+class __extend__(pairtype(SomeInstance, SomeException)):
+    def union((s_inst, s_exc)):
+        return unionof(s_exc.as_SomeInstance(), s_inst)
+
 
 @op.getitem.register_transform(SomeInstance, SomeObject)
 def getitem_SomeInstance(annotator, v_ins, v_idx):
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -12,7 +12,7 @@
 from rpython.annotator.model import (
     SomeOrderedDict, SomeString, SomeChar, SomeFloat, unionof, SomeInstance,
     SomeDict, SomeBuiltin, SomePBC, SomeInteger, TLS, SomeUnicodeCodePoint,
-    s_None, s_ImpossibleValue, SomeBool, SomeTuple,
+    s_None, s_ImpossibleValue, SomeBool, SomeTuple, SomeException,
     SomeImpossibleValue, SomeUnicodeString, SomeList, HarmlesslyBlocked,
     SomeWeakRef, SomeByteArray, SomeConstantType, SomeProperty)
 from rpython.annotator.classdesc import ClassDef, ClassDesc
@@ -167,6 +167,10 @@
         desc = self.getdesc(cls)
         return desc.getuniqueclassdef()
 
+    def new_exception(self, exc_classes):
+        clsdefs = {self.getuniqueclassdef(cls) for cls in exc_classes}
+        return SomeException(clsdefs)
+
     def getlistdef(self, **flags_if_new):
         """Get the ListDef associated with the current position."""
         try:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -452,27 +452,27 @@
 
 class SomeException(SomeObject):
     """The set of exceptions obeying type(exc) in self.classes"""
-    def __init__(self, classes):
-        self.classes = classes
+    def __init__(self, classdefs):
+        self.classdefs = classdefs
 
     def intersection(self, other):
         assert isinstance(other, SomeExceptCase)
-        classes = {c for c in self.classes if issubclass(c, other.case)}
-        if classes:
-            return SomeException(classes)
+        classdefs = {c for c in self.classdefs if c.issubclass(other.case)}
+        if classdefs:
+            return SomeException(classdefs)
         else:
             return s_ImpossibleValue
 
     def difference(self, other):
         assert isinstance(other, SomeExceptCase)
-        classes = {c for c in self.classes if not issubclass(c, other.case)}
-        if classes:
-            return SomeException(classes)
+        classdefs = {c for c in self.classdefs if not c.issubclass(other.case)}
+        if classdefs:
+            return SomeException(classdefs)
         else:
             return s_ImpossibleValue
 
-    def as_SomeInstance(self, bk):
-        return unionof(*[bk.valueoftype(cls) for cls in self.classes])
+    def as_SomeInstance(self):
+        return unionof(*[SomeInstance(cdef) for cdef in self.classdefs])
 
 
 class SomeExceptCase(SomeObject):
diff --git a/rpython/annotator/test/test_model.py 
b/rpython/annotator/test/test_model.py
--- a/rpython/annotator/test/test_model.py
+++ b/rpython/annotator/test/test_model.py
@@ -3,6 +3,7 @@
 from rpython.annotator.model import *
 from rpython.annotator.listdef import ListDef
 from rpython.translator.translator import TranslationContext
+from rpython.annotator import unaryop, binaryop  # for side-effects
 
 @pytest.fixture()
 def annotator():
@@ -136,3 +137,11 @@
     assert s.no_nul is True
     s = SomeChar().nonnulify()
     assert s.no_nul is True
+
+def test_SomeException_union(annotator):
+    bk = annotator.bookkeeper
+    someinst = lambda cls, **kw: SomeInstance(bk.getuniqueclassdef(cls), **kw)
+    s_inst = someinst(Exception)
+    s_exc = bk.new_exception([ValueError, IndexError])
+    assert unionof(s_exc, s_inst) == s_inst
+    assert unionof(s_inst, s_exc) == s_inst
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to