Author: Ronan Lamy <[email protected]>
Branch: anntype2
Changeset: r80841:5acb90f641dd
Date: 2015-11-23 04:51 +0000
http://bitbucket.org/pypy/pypy/changeset/5acb90f641dd/
Log: Use @doubledispatch for intersection() and difference()
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -11,7 +11,7 @@
from rpython.translator import simplify, transform
from rpython.annotator import model as annmodel, signature
from rpython.annotator.model import (
- typeof, s_ImpossibleValue, SomeInstance)
+ typeof, s_ImpossibleValue, SomeInstance, intersection, difference)
from rpython.annotator.bookkeeper import Bookkeeper
from rpython.rtyper.normalizecalls import perform_normalizations
@@ -497,14 +497,14 @@
if s_exception == s_ImpossibleValue:
break
s_case = SomeInstance(self.bookkeeper.getuniqueclassdef(case))
- s_matching_exc = s_exception.intersection(s_case)
+ s_matching_exc = intersection(s_exception, s_case)
if s_matching_exc != s_ImpossibleValue:
self.follow_raise_link(graph, link, s_matching_exc)
- s_exception = s_exception.difference(s_case)
+ s_exception = difference(s_exception, s_case)
else:
if isinstance(block.exitswitch, Variable):
- knowntypedata = getattr(block.exitswitch.annotation,
- "knowntypedata", {})
+ knowntypedata = getattr(
+ block.exitswitch.annotation, "knowntypedata", {})
else:
knowntypedata = {}
for link in exits:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -36,7 +36,7 @@
import rpython
from rpython.tool import descriptor
-from rpython.tool.pairtype import pair, extendabletype
+from rpython.tool.pairtype import pair, extendabletype, doubledispatch
from rpython.rlib.rarithmetic import r_uint, base_int, r_singlefloat,
r_longfloat
@@ -129,6 +129,16 @@
def nonnoneify(self):
return self
+@doubledispatch
+def intersection(s_obj1, s_obj2):
+ """Return the intersection of two annotations, or an over-approximation
thereof"""
+ raise NotImplementedError
+
+@doubledispatch
+def difference(s_obj1, s_obj2):
+ """Return the set difference of two annotations, or an over-approximation
thereof"""
+ raise NotImplementedError
+
class SomeType(SomeObject):
"Stands for a type. We might not be sure which one it is."
@@ -445,23 +455,6 @@
else:
return None
- def intersection(self, other):
- assert isinstance(other, SomeInstance)
- can_be_None = self.can_be_None and other.can_be_None
- if self.classdef.issubclass(other.classdef):
- return SomeInstance(self.classdef, can_be_None=can_be_None)
- elif other.classdef.issubclass(self.classdef):
- return SomeInstance(other.classdef, can_be_None=can_be_None)
- else:
- return s_ImpossibleValue
-
- def difference(self, other):
- assert isinstance(other, SomeInstance)
- if self.classdef.issubclass(other.classdef):
- return s_ImpossibleValue
- else:
- return self
-
def can_be_none(self):
return self.can_be_None
@@ -471,30 +464,52 @@
def noneify(self):
return SomeInstance(self.classdef, can_be_None=True)
[email protected](SomeInstance, SomeInstance)
+def intersection_Instance(s_inst1, s_inst2):
+ can_be_None = s_inst1.can_be_None and s_inst2.can_be_None
+ if s_inst1.classdef.issubclass(s_inst2.classdef):
+ return SomeInstance(s_inst1.classdef, can_be_None=can_be_None)
+ elif s_inst2.classdef.issubclass(s_inst1.classdef):
+ return SomeInstance(s_inst2.classdef, can_be_None=can_be_None)
+ else:
+ return s_ImpossibleValue
+
[email protected](SomeInstance, SomeInstance)
+def difference_Instance_Instance(s_inst1, s_inst2):
+ if s_inst1.classdef.issubclass(s_inst2.classdef):
+ return s_ImpossibleValue
+ else:
+ return s_inst1
+
+
class SomeException(SomeObject):
"""The set of exceptions obeying type(exc) in self.classes"""
def __init__(self, classdefs):
self.classdefs = classdefs
- def intersection(self, other):
- assert isinstance(other, SomeInstance)
- classdefs = {c for c in self.classdefs if c.issubclass(other.classdef)}
- if classdefs:
- return SomeException(classdefs)
- else:
- return s_ImpossibleValue
-
- def difference(self, other):
- assert isinstance(other, SomeInstance)
- classdefs = {c for c in self.classdefs if not
c.issubclass(other.classdef)}
- if classdefs:
- return SomeException(classdefs)
- else:
- return s_ImpossibleValue
-
def as_SomeInstance(self):
return unionof(*[SomeInstance(cdef) for cdef in self.classdefs])
[email protected](SomeException, SomeInstance)
+def intersection_Exception_Instance(s_exc, s_inst):
+ classdefs = {c for c in s_exc.classdefs if c.issubclass(s_inst.classdef)}
+ if classdefs:
+ return SomeException(classdefs)
+ else:
+ return s_ImpossibleValue
+
[email protected](SomeInstance, SomeException)
+def intersection_Exception_Instance(s_inst, s_exc):
+ return intersection(s_exc, s_inst)
+
[email protected](SomeException, SomeInstance)
+def difference_Exception_Instance(s_exc, s_inst):
+ classdefs = {c for c in s_exc.classdefs
+ if not c.issubclass(s_inst.classdef)}
+ if classdefs:
+ return SomeException(classdefs)
+ else:
+ return s_ImpossibleValue
class SomePBC(SomeObject):
"""Stands for a global user instance, built prior to the analysis,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit