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