Author: Armin Rigo <ar...@tunes.org> Branch: kill-someobject Changeset: r57807:fa72a07de9f2 Date: 2012-10-07 12:56 +0200 http://bitbucket.org/pypy/pypy/changeset/fa72a07de9f2/
Log: (fijal, arigo) A branch to really kill SomeObject support. Kill kill kill old old old code. diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py --- a/pypy/annotation/annrpython.py +++ b/pypy/annotation/annrpython.py @@ -39,21 +39,8 @@ self.notify = {} # {block: {positions-to-reflow-from-when-done}} self.fixed_graphs = {} # set of graphs not to annotate again self.blocked_blocks = {} # set of {blocked_block: graph} - # --- the following information is recorded for debugging only --- - # --- and only if annotation.model.DEBUG is kept to True - self.why_not_annotated = {} # {block: (exc_type, exc_value, traceback)} - # records the location of BlockedInference - # exceptions that blocked some blocks. + # --- the following information is recorded for debugging --- self.blocked_graphs = {} # set of graphs that have blocked blocks - self.bindingshistory = {}# map Variables to lists of SomeValues - self.binding_caused_by = {} # map Variables to position_keys - # records the caller position that caused bindings of inputargs - # to be updated - self.binding_cause_history = {} # map Variables to lists of positions - # history of binding_caused_by, kept in sync with - # bindingshistory - self.reflowcounter = {} - self.return_bindings = {} # map return Variables to their graphs # --- end of debugging information --- self.frozen = False if policy is None: @@ -77,10 +64,6 @@ ret[key] = {} return ret - def _register_returnvar(self, flowgraph): - if annmodel.DEBUG: - self.return_bindings[flowgraph.getreturnvar()] = flowgraph - #___ convenience high-level interface __________________ def build_types(self, function, input_arg_types, complete_now=True, @@ -182,10 +165,9 @@ #___ medium-level interface ____________________________ def addpendinggraph(self, flowgraph, inputcells): - self._register_returnvar(flowgraph) self.addpendingblock(flowgraph, flowgraph.startblock, inputcells) - def addpendingblock(self, graph, block, cells, called_from_graph=None): + def addpendingblock(self, graph, block, cells): """Register an entry point into block with the given input cells.""" if graph in self.fixed_graphs: # special case for annotating/rtyping in several phases: calling @@ -200,9 +182,9 @@ for a in cells: assert isinstance(a, annmodel.SomeObject) if block not in self.annotated: - self.bindinputargs(graph, block, cells, called_from_graph) + self.bindinputargs(graph, block, cells) else: - self.mergeinputargs(graph, block, cells, called_from_graph) + self.mergeinputargs(graph, block, cells) if not self.annotated[block]: self.pendingblocks[block] = graph @@ -211,8 +193,6 @@ while True: while self.pendingblocks: block, graph = self.pendingblocks.popitem() - if annmodel.DEBUG: - self.flowin_block = block # we need to keep track of block self.processblock(graph, block) self.policy.no_more_blocks_to_annotate(self) if not self.pendingblocks: @@ -263,60 +243,14 @@ def typeannotation(self, t): return signature.annotation(t, self.bookkeeper) - def ondegenerated(self, what, s_value, where=None, called_from_graph=None): - if self.policy.allow_someobjects: - return - # is the function itself tagged with allow_someobjects? - position_key = where or getattr(self.bookkeeper, 'position_key', None) - if position_key is not None: - graph, block, i = position_key - try: - if graph.func.allow_someobjects: - return - except AttributeError: - pass - - msgstr = format_someobject_error(self, position_key, what, s_value, - called_from_graph, - self.bindings.get(what, "(none)")) - - raise AnnotatorError(msgstr) - - def setbinding(self, arg, s_value, called_from_graph=None, where=None): + def setbinding(self, arg, s_value): if arg in self.bindings: assert s_value.contains(self.bindings[arg]) - # for debugging purposes, record the history of bindings that - # have been given to this variable - if annmodel.DEBUG: - history = self.bindingshistory.setdefault(arg, []) - history.append(self.bindings[arg]) - cause_history = self.binding_cause_history.setdefault(arg, []) - cause_history.append(self.binding_caused_by[arg]) - - degenerated = annmodel.isdegenerated(s_value) - - if degenerated: - self.ondegenerated(arg, s_value, where=where, - called_from_graph=called_from_graph) - self.bindings[arg] = s_value - if annmodel.DEBUG: - if arg in self.return_bindings: - log.event("%s -> %s" % - (self.whereami((self.return_bindings[arg], None, None)), - s_value)) - - if arg in self.return_bindings and degenerated: - self.warning("result degenerated to SomeObject", - (self.return_bindings[arg],None, None)) - - self.binding_caused_by[arg] = called_from_graph def transfer_binding(self, v_target, v_source): assert v_source in self.bindings self.bindings[v_target] = self.bindings[v_source] - if annmodel.DEBUG: - self.binding_caused_by[v_target] = None def warning(self, msg, pos=None): if pos is None: @@ -332,14 +266,11 @@ #___ interface for annotator.bookkeeper _______ - def recursivecall(self, graph, whence, inputcells): # whence = position_key|callback taking the annotator, graph + def recursivecall(self, graph, whence, inputcells): if isinstance(whence, tuple): - parent_graph, parent_block, parent_index = position_key = whence + parent_graph, parent_block, parent_index = whence tag = parent_block, parent_index self.translator.update_call_graph(parent_graph, graph, tag) - else: - position_key = None - self._register_returnvar(graph) # self.notify[graph.returnblock] is a dictionary of call # points to this func which triggers a reflow whenever the # return block of this graph has been analysed. @@ -353,8 +284,7 @@ callpositions[callback] = True # generalize the function's input arguments - self.addpendingblock(graph, graph.startblock, inputcells, - position_key) + self.addpendingblock(graph, graph.startblock, inputcells) # get the (current) return value v = graph.getreturnvar() @@ -404,9 +334,6 @@ # input variables). #print '* processblock', block, cells - if annmodel.DEBUG: - self.reflowcounter.setdefault(block, 0) - self.reflowcounter[block] += 1 self.annotated[block] = graph if block in self.blocked_blocks: del self.blocked_blocks[block] @@ -435,23 +362,22 @@ self.annotated[block] = False # must re-flow self.blocked_blocks[block] = graph - def bindinputargs(self, graph, block, inputcells, called_from_graph=None): + def bindinputargs(self, graph, block, inputcells): # Create the initial bindings for the input args of a block. assert len(block.inputargs) == len(inputcells) - where = (graph, block, None) for a, cell in zip(block.inputargs, inputcells): - self.setbinding(a, cell, called_from_graph, where=where) + self.setbinding(a, cell) self.annotated[block] = False # must flowin. self.blocked_blocks[block] = graph - def mergeinputargs(self, graph, block, inputcells, called_from_graph=None): + def mergeinputargs(self, graph, block, inputcells): # Merge the new 'cells' with each of the block's existing input # variables. oldcells = [self.binding(a) for a in block.inputargs] unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)] # if the merged cells changed, we must redo the analysis if unions != oldcells: - self.bindinputargs(graph, block, unions, called_from_graph) + self.bindinputargs(graph, block, unions) def whereami(self, position_key): graph, block, i = position_key @@ -476,9 +402,6 @@ self.bookkeeper.leave() except BlockedInference, e: - if annmodel.DEBUG: - self.why_not_annotated[block] = sys.exc_info() - if (e.op is block.operations[-1] and block.exitswitch == c_last_exception): # this is the case where the last operation of the block will @@ -562,8 +485,7 @@ and issubclass(link.exitcase, py.builtin.BaseException): assert last_exception_var and last_exc_value_var last_exc_value_object = self.bookkeeper.valueoftype(link.exitcase) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value last_exception_object.is_type_of = [last_exc_value_var] @@ -573,8 +495,7 @@ if isinstance(last_exc_value_var, Variable): self.setbinding(last_exc_value_var, last_exc_value_object) - last_exception_object = annmodel.SomeObject() - last_exception_object.knowntype = type + last_exception_object = annmodel.SomeType() if isinstance(last_exception_var, Constant): last_exception_object.const = last_exception_var.value #if link.exitcase is Exception: @@ -610,9 +531,8 @@ for v in cell.is_type_of: new_vs = renaming.get(v,[]) renamed_is_type_of += new_vs - newcell = annmodel.SomeObject() - if cell.knowntype == type: - newcell.knowntype = type + assert cell.knowntype is type + newcell = annmodel.SomeType() if cell.is_constant(): newcell.const = cell.const cell = newcell diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py --- a/pypy/annotation/binaryop.py +++ b/pypy/annotation/binaryop.py @@ -13,9 +13,9 @@ from pypy.annotation.model import SomePBC, SomeFloat, s_None from pypy.annotation.model import SomeExternalObject, SomeWeakRef from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess -from pypy.annotation.model import SomeSingleFloat, SomeLongFloat +from pypy.annotation.model import SomeSingleFloat, SomeLongFloat, SomeType from pypy.annotation.model import unionof, UnionError, missing_operation -from pypy.annotation.model import isdegenerated, TLS +from pypy.annotation.model import TLS from pypy.annotation.model import read_can_only_throw from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.model import SomeGenericCallable @@ -29,15 +29,6 @@ def immutablevalue(x): return getbookkeeper().immutablevalue(x) -def unioncheck(*somevalues): - s_value = unionof(*somevalues) - if isdegenerated(s_value): - if not getattr(TLS, 'no_side_effects_in_union', 0): - bookkeeper = getbookkeeper() - if bookkeeper is not None: - bookkeeper.ondegenerated('union', s_value) - return s_value - # XXX unify this with ObjSpace.MethodTable BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod', 'truediv', 'floordiv', 'divmod', 'pow', @@ -64,35 +55,7 @@ class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): - if obj1 == obj2: - return obj1 - else: - result = SomeObject() - if obj1.knowntype == obj2.knowntype and obj1.knowntype != object: - result.knowntype = obj1.knowntype - is_type_of1 = getattr(obj1, 'is_type_of', None) - is_type_of2 = getattr(obj2, 'is_type_of', None) - if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: - result.const = obj1.const - is_type_of = {} - if is_type_of1: - for v in is_type_of1: - is_type_of[v] = True - if is_type_of2: - for v in is_type_of2: - is_type_of[v] = True - if is_type_of: - result.is_type_of = is_type_of.keys() - else: - if is_type_of1 and is_type_of1 == is_type_of2: - result.is_type_of = is_type_of1 - # try to preserve the origin of SomeObjects - if obj1 == result: - result = obj1 - elif obj2 == result: - result = obj2 - unioncheck(result) - return result + raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() @@ -238,7 +201,30 @@ getitem_idx = getitem_idx_key getitem_key = getitem_idx_key - + + +class __extend__(pairtype(SomeType, SomeType)): + + def union((obj1, obj2)): + result = SomeType() + is_type_of1 = getattr(obj1, 'is_type_of', None) + is_type_of2 = getattr(obj2, 'is_type_of', None) + if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const: + result.const = obj1.const + is_type_of = {} + if is_type_of1: + for v in is_type_of1: + is_type_of[v] = True + if is_type_of2: + for v in is_type_of2: + is_type_of[v] = True + if is_type_of: + result.is_type_of = is_type_of.keys() + else: + if is_type_of1 and is_type_of1 == is_type_of2: + result.is_type_of = is_type_of1 + return result + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): @@ -566,7 +552,7 @@ if len(tup1.items) != len(tup2.items): return SomeObject() else: - unions = [unioncheck(x,y) for x,y in zip(tup1.items, tup2.items)] + unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)] return SomeTuple(items = unions) def add((tup1, tup2)): @@ -723,8 +709,7 @@ else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: - # print warning? - return SomeObject() + raise UnionError(ins1, ins2) flags = ins1.flags if flags: flags = flags.copy() @@ -764,7 +749,7 @@ class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): - s_cont = unioncheck(iter1.s_container, iter2.s_container) + s_cont = unionof(iter1.s_container, iter2.s_container) if iter1.variant != iter2.variant: raise UnionError("merging incompatible iterators variants") return SomeIterator(s_cont, *iter1.variant) @@ -778,7 +763,7 @@ bltn1.s_self is None or bltn2.s_self is None): raise UnionError("cannot merge two different builtin functions " "or methods:\n %r\n %r" % (bltn1, bltn2)) - s_self = unioncheck(bltn1.s_self, bltn2.s_self) + s_self = unionof(bltn1.s_self, bltn2.s_self) return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) class __extend__(pairtype(SomePBC, SomePBC)): @@ -806,7 +791,7 @@ unique_key = desc bk = desc.bookkeeper s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s) - s_result = unioncheck(s_result, gencall.s_result) + s_result = unionof(s_result, gencall.s_result) assert gencall.s_result.contains(s_result) return gencall diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py --- a/pypy/annotation/bookkeeper.py +++ b/pypy/annotation/bookkeeper.py @@ -10,7 +10,7 @@ SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \ SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ SomeUnicodeString, SomeList, SomeObject, HarmlesslyBlocked, \ - SomeWeakRef, lltype_to_annotation + SomeWeakRef, lltype_to_annotation, SomeType from pypy.annotation.classdef import InstanceSource, ClassDef from pypy.annotation.listdef import ListDef, ListItem from pypy.annotation.dictdef import DictDef @@ -325,8 +325,6 @@ if hasattr(x, 'im_self') and x.im_self is None: x = x.im_func assert not hasattr(x, 'im_self') - if x is sys: # special case constant sys to someobject - return SomeObject() tp = type(x) if issubclass(tp, Symbolic): # symbolic constants support result = x.annotation() @@ -445,6 +443,11 @@ result = SomeOOInstance(ootype.typeOf(x)) elif isinstance(x, (ootype._object)): result = SomeOOObject() + elif tp is type: + if x is type(None): # add cases here if needed + result = SomeType() + else: + result = SomePBC([self.getdesc(x)]) elif callable(x): if hasattr(x, 'im_self') and hasattr(x, 'im_func'): # on top of PyPy, for cases like 'l.append' where 'l' is a @@ -455,19 +458,11 @@ # for cases like 'l.append' where 'l' is a global constant list s_self = self.immutablevalue(x.__self__, need_const) result = s_self.find_method(x.__name__) - if result is None: - result = SomeObject() + assert result is not None else: result = None if result is None: - if (self.annotator.policy.allow_someobjects - and getattr(x, '__module__', None) == '__builtin__' - # XXX note that the print support functions are __builtin__ - and tp not in (types.FunctionType, types.MethodType)): - result = SomeObject() - result.knowntype = tp # at least for types this needs to be correct - else: - result = SomePBC([self.getdesc(x)]) + result = SomePBC([self.getdesc(x)]) elif hasattr(x, '_freeze_') and x._freeze_(): # user-defined classes can define a method _freeze_(), which # is called when a prebuilt instance is found. If the method diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py --- a/pypy/annotation/builtin.py +++ b/pypy/annotation/builtin.py @@ -158,18 +158,12 @@ else: if typ == long: getbookkeeper().warning("isinstance(., long) is not RPython") - if s_obj.is_constant(): - r.const = isinstance(s_obj.const, long) - else: - if type(s_obj) is not SomeObject: # only SomeObjects could be longs - # type(s_obj) < SomeObject -> SomeBool(False) - # type(s_obj) == SomeObject -> SomeBool() - r.const = False + r.const = False return r - + assert not issubclass(typ, (int, long)) or typ in (bool, int, long), ( "for integers only isinstance(.,int|r_uint) are supported") - + if s_obj.is_constant(): r.const = isinstance(s_obj.const, typ) elif our_issubclass(s_obj.knowntype, typ): @@ -195,8 +189,7 @@ for variable in variables: assert bk.annotator.binding(variable) == s_obj r.knowntypedata = {} - if (not isinstance(s_type, SomeBuiltin) - or typ.__module__ == '__builtin__'): + if not isinstance(s_type, SomeBuiltin): add_knowntypedata(r.knowntypedata, True, variables, bk.valueoftype(typ)) return r diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py --- a/pypy/annotation/classdef.py +++ b/pypy/annotation/classdef.py @@ -2,8 +2,7 @@ Type inference for user-defined classes. """ from pypy.annotation.model import SomePBC, s_ImpossibleValue, unionof -from pypy.annotation.model import SomeInteger, isdegenerated, SomeTuple,\ - SomeString +from pypy.annotation.model import SomeInteger, SomeTuple, SomeString from pypy.annotation import description @@ -79,11 +78,7 @@ if source.instance_level: # a prebuilt instance source forces readonly=False, see above self.modified(classdef) - s_new_value = unionof(self.s_value, s_value) - if isdegenerated(s_new_value): - self.bookkeeper.ondegenerated("source %r attr %s" % (source, self.name), - s_new_value) - + s_new_value = unionof(self.s_value, s_value) # XXX "source %r attr %s" % (source, self.name), self.s_value = s_new_value def getvalue(self): @@ -92,11 +87,7 @@ def merge(self, other, classdef='?'): assert self.name == other.name - s_new_value = unionof(self.s_value, other.s_value) - if isdegenerated(s_new_value): - what = "%s attr %s" % (classdef, self.name) - self.bookkeeper.ondegenerated(what, s_new_value) - + s_new_value = unionof(self.s_value, other.s_value) # XXX "%s attr %s" % (classdef, self.name) self.s_value = s_new_value if not other.readonly: self.modified(classdef) diff --git a/pypy/annotation/dictdef.py b/pypy/annotation/dictdef.py --- a/pypy/annotation/dictdef.py +++ b/pypy/annotation/dictdef.py @@ -119,13 +119,9 @@ self.dictvalue is other.dictvalue) def union(self, other): - if (self.same_as(MOST_GENERAL_DICTDEF) or - other.same_as(MOST_GENERAL_DICTDEF)): - return MOST_GENERAL_DICTDEF # without merging - else: - self.dictkey.merge(other.dictkey) - self.dictvalue.merge(other.dictvalue) - return self + self.dictkey.merge(other.dictkey) + self.dictvalue.merge(other.dictvalue) + return self def generalize_key(self, s_key): self.dictkey.generalize(s_key) @@ -143,6 +139,3 @@ def __repr__(self): return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value) - - -MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject()) diff --git a/pypy/annotation/listdef.py b/pypy/annotation/listdef.py --- a/pypy/annotation/listdef.py +++ b/pypy/annotation/listdef.py @@ -1,6 +1,6 @@ from pypy.annotation.model import SomeObject, s_ImpossibleValue from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.model import unionof, TLS, UnionError, isdegenerated +from pypy.annotation.model import unionof, TLS, UnionError class TooLateForChange(Exception): @@ -92,11 +92,6 @@ if s_new_value != s_value: if self.dont_change_any_more: raise TooLateForChange - if isdegenerated(s_new_value): - if self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) - elif other.bookkeeper: - other.bookkeeper.ondegenerated(other, s_new_value) self.patch() # which should patch all refs to 'other' if s_new_value != s_value: self.s_value = s_new_value @@ -114,8 +109,6 @@ def generalize(self, s_other_value): s_new_value = unionof(self.s_value, s_other_value) - if isdegenerated(s_new_value) and self.bookkeeper: - self.bookkeeper.ondegenerated(self, s_new_value) updated = s_new_value != self.s_value if updated: if self.dont_change_any_more: @@ -157,12 +150,8 @@ return self.listitem is other.listitem def union(self, other): - if (self.same_as(MOST_GENERAL_LISTDEF) or - other.same_as(MOST_GENERAL_LISTDEF)): - return MOST_GENERAL_LISTDEF # without merging - else: - self.listitem.merge(other.listitem) - return self + self.listitem.merge(other.listitem) + return self def agree(self, other): s_self_value = self.read_item() @@ -221,7 +210,5 @@ #else: it's fine, don't set immutable=True at all (see # test_can_merge_immutable_list_with_regular_list) -MOST_GENERAL_LISTDEF = ListDef(None, SomeObject()) - s_list_of_strings = SomeList(ListDef(None, SomeString(no_nul=True), resized = True)) diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py --- a/pypy/annotation/model.py +++ b/pypy/annotation/model.py @@ -36,8 +36,6 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat import inspect, weakref -DEBUG = False # set to False to disable recording of debugging information - class State(object): # A global attribute :-( Patch it with 'True' to enable checking of # the no_nul attribute... @@ -48,9 +46,11 @@ """The set of all objects. Each instance stands for an arbitrary object about which nothing is known.""" __metaclass__ = extendabletype - knowntype = object immutable = False + def __init__(self): + assert type(self) is not SomeObject + def __eq__(self, other): return (self.__class__ is other.__class__ and self.__dict__ == other.__dict__) @@ -105,61 +105,28 @@ return self.immutable and 'const' in self.__dict__ # delegate accesses to 'const' to accesses to 'const_box.value', - # where const_box is a Constant. XXX the idea is to eventually - # use systematically 'const_box' instead of 'const' for - # non-immutable constant annotations + # where const_box is a Constant. This is not a property, in order + # to allow 'self.const = xyz' to work as well. class ConstAccessDelegator(object): def __get__(self, obj, cls=None): return obj.const_box.value const = ConstAccessDelegator() del ConstAccessDelegator - # for debugging, record where each instance comes from - # this is disabled if DEBUG is set to False - def __new__(cls, *args, **kw): - new = super(SomeObject, cls).__new__ - if new is object.__new__: - # Since python 2.6, object.__new__ warns - # when parameters are passed - self = new(cls) - else: - self = new(cls, *args, **kw) - if DEBUG: - try: - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - position_key = bookkeeper.position_key - except AttributeError: - pass - else: - bookkeeper._isomeobject_coming_from[self] = position_key, None - return self - - def origin(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] - origin = property(origin) - - def caused_by_merge(self): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return None - return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] - def set_caused_by_merge(self, nvalue): - bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() - if bookkeeper is None: - return - bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue - caused_by_merge = property(caused_by_merge, set_caused_by_merge) - del set_caused_by_merge - def can_be_none(self): return True def nonnoneify(self): return self +class SomeType(SomeObject): + "Stands for a type. We might not be sure which one it is." + knowntype = type + immutable = True + + def can_be_none(self): + return False + 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, @@ -517,6 +484,7 @@ s_None = SomePBC([], can_be_None=True) s_Bool = SomeBool() +s_Int = SomeInteger() s_ImpossibleValue = SomeImpossibleValue() s_Str0 = SomeString(no_nul=True) @@ -710,14 +678,8 @@ # this is just a performance shortcut if s1 != s2: s1 = pair(s1, s2).union() - if DEBUG: - if s1.caused_by_merge is None and len(somevalues) > 1: - s1.caused_by_merge = somevalues return s1 -def isdegenerated(s_value): - return s_value.__class__ is SomeObject and s_value.knowntype is not type - # make knowntypedata dictionary def add_knowntypedata(ktd, truth, vars, s_obj): diff --git a/pypy/annotation/policy.py b/pypy/annotation/policy.py --- a/pypy/annotation/policy.py +++ b/pypy/annotation/policy.py @@ -10,7 +10,6 @@ class BasicAnnotatorPolicy(object): - allow_someobjects = True def event(pol, bookkeeper, what, *args): pass diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py --- a/pypy/annotation/signature.py +++ b/pypy/annotation/signature.py @@ -3,9 +3,9 @@ from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\ SomeFloat, SomeList, SomeDict, s_None, \ SomeObject, SomeInstance, SomeTuple, lltype_to_annotation,\ - unionof, SomeUnicodeString -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF -from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF + unionof, SomeUnicodeString, SomeType +from pypy.annotation.listdef import ListDef +from pypy.annotation.dictdef import DictDef _annotation_cache = {} @@ -78,13 +78,10 @@ return SomeString() elif t is unicode: return SomeUnicodeString() - elif t is list: - return SomeList(MOST_GENERAL_LISTDEF) - elif t is dict: - return SomeDict(MOST_GENERAL_DICTDEF) - # can't do tuple elif t is types.NoneType: return s_None + elif t is type: + return SomeType() elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy): entry = extregistry.lookup_type(t, bookkeeper.policy) return entry.compute_annotation_bk(bookkeeper) @@ -92,10 +89,7 @@ classdef = bookkeeper.getuniqueclassdef(t) return SomeInstance(classdef) else: - o = SomeObject() - if t != object: - o.knowntype = t - return o + raise AssertionError("annotationoftype(%r)" % (t,)) class Sig(object): diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py --- a/pypy/annotation/test/test_annrpython.py +++ b/pypy/annotation/test/test_annrpython.py @@ -24,7 +24,7 @@ assert isinstance(s_list, annmodel.SomeList) return s_list.listdef.listitem.s_value -def somelist(s_type=annmodel.SomeObject()): +def somelist(s_type): return annmodel.SomeList(ListDef(None, s_type)) def dictkey(s_dict): @@ -35,7 +35,7 @@ assert isinstance(s_dict, annmodel.SomeDict) return s_dict.dictdef.dictvalue.s_value -def somedict(s_key=annmodel.SomeObject(), s_value=annmodel.SomeObject()): +def somedict(s_key, s_value): return annmodel.SomeDict(DictDef(None, s_key, s_value)) @@ -205,15 +205,6 @@ annmodel.SomeInteger() ]) - def test_inheritance2(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet._inheritance_nonrunnable, []) - # result should be exactly: - assert s == annmodel.SomeTuple([ - annmodel.SomeInteger(), - annmodel.SomeObject() - ]) - def test_poor_man_range(self): a = self.RPythonAnnotator() s = a.build_types(snippet.poor_man_range, [int]) @@ -336,9 +327,13 @@ def test_flow_type_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_type_info, [object]) + s = a.build_types(snippet.flow_type_info, [int]) a.simplify() - #a.translator.view() + assert s.knowntype == int + + a = self.RPythonAnnotator() + s = a.build_types(snippet.flow_type_info, [str]) + a.simplify() assert s.knowntype == int def test_flow_type_info_2(self): @@ -351,7 +346,7 @@ def test_flow_usertype_info(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_usertype_info, [object]) + s = a.build_types(snippet.flow_usertype_info, [snippet.WithInit]) #a.translator.view() assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithInit) @@ -363,13 +358,6 @@ assert isinstance(s, annmodel.SomeInstance) assert s.classdef == a.bookkeeper.getuniqueclassdef(snippet.WithMoreInit) - def test_flow_identity_info(self): - a = self.RPythonAnnotator() - s = a.build_types(snippet.flow_identity_info, [object, object]) - a.simplify() - #a.translator.view() - assert s == a.bookkeeper.immutablevalue((None, None)) - def test_mergefunctions(self): a = self.RPythonAnnotator() s = a.build_types(snippet.mergefunctions, [int]) @@ -431,11 +419,11 @@ # the annotator (it doesn't check that they operate property, though) for example, methname, s_example in [ ('', 'join', annmodel.SomeString()), - ([], 'append', somelist()), - ([], 'extend', somelist()), - ([], 'reverse', somelist()), - ([], 'insert', somelist()), - ([], 'pop', somelist()), + ([], 'append', somelist(annmodel.s_Int)), + ([], 'extend', somelist(annmodel.s_Int)), + ([], 'reverse', somelist(annmodel.s_Int)), + ([], 'insert', somelist(annmodel.s_Int)), + ([], 'pop', somelist(annmodel.s_Int)), ]: constmeth = getattr(example, methname) s_constmeth = iv(constmeth) @@ -497,12 +485,12 @@ def test_simple_slicing(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_slice, [list]) + s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeList) def test_simple_iter_list(self): a = self.RPythonAnnotator() - s = a.build_types(snippet.simple_iter, [list]) + s = a.build_types(snippet.simple_iter, [somelist(annmodel.s_Int)]) assert isinstance(s, annmodel.SomeIterator) def test_simple_iter_next(self): @@ -542,11 +530,6 @@ assert isinstance(dictkey(s), annmodel.SomeInteger) assert isinstance(dictvalue(s), annmodel.SomeInteger) - a = self.RPythonAnnotator() - s = a.build_types(snippet.dict_update, [str]) - assert not isinstance(dictkey(s), annmodel.SomeString) - assert not isinstance(dictvalue(s), annmodel.SomeString) - def test_dict_update_2(self): a = self.RPythonAnnotator() def g(n): @@ -568,7 +551,7 @@ def test_dict_keys2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_keys2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_values(self): a = self.RPythonAnnotator() @@ -578,7 +561,7 @@ def test_dict_values2(self): a = self.RPythonAnnotator() s = a.build_types(snippet.dict_values2, []) - assert not isinstance(listitem(s), annmodel.SomeString) + assert type(listitem(s)) is annmodel.SomeString def test_dict_items(self): a = self.RPythonAnnotator() @@ -643,25 +626,6 @@ s = a.build_types(operation_always_raising, [int]) assert s == a.bookkeeper.immutablevalue(24) - def test_bltin_code_frame_confusion(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_confusion,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - # annotator confused by original bltin code/frame setup, we just get SomeObject here - assert a.binding(f_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - assert a.binding(g_flowgraph.getreturnvar()).__class__ is annmodel.SomeObject - - def test_bltin_code_frame_reorg(self): - a = self.RPythonAnnotator() - a.build_types(snippet.bltin_code_frame_reorg,[]) - f_flowgraph = graphof(a, snippet.bltin_code_frame_f) - g_flowgraph = graphof(a, snippet.bltin_code_frame_g) - assert isinstance(a.binding(f_flowgraph.getreturnvar()), - annmodel.SomeInteger) - assert isinstance(a.binding(g_flowgraph.getreturnvar()), - annmodel.SomeString) - def test_propagation_of_fresh_instances_through_attrs(self): a = self.RPythonAnnotator() s = a.build_types(snippet.propagation_of_fresh_instances_through_attrs, [int]) @@ -748,14 +712,15 @@ assert s.classdef is a.bookkeeper.getuniqueclassdef(snippet.Exc) def test_type_is(self): - class C(object): + class B(object): + pass + class C(B): pass def f(x): - if type(x) is C: - return x - raise Exception - a = self.RPythonAnnotator() - s = a.build_types(f, [object]) + assert type(x) is C + return x + a = self.RPythonAnnotator() + s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) def test_ann_assert(self): @@ -793,7 +758,7 @@ return None a = self.RPythonAnnotator() - s = a.build_types(f, [list]) + s = a.build_types(f, [somelist(annmodel.s_Int)]) assert s.classdef is a.bookkeeper.getuniqueclassdef(IndexError) # KeyError ignored because l is a list def test_freeze_protocol(self): @@ -854,7 +819,7 @@ def f(a,b): return bool(a) or bool(b) a = self.RPythonAnnotator() - s = a.build_types(f, [int,list]) + s = a.build_types(f, [int, somelist(annmodel.s_Int)]) assert s.knowntype == bool def test_float(self): @@ -1299,22 +1264,6 @@ assert isinstance(s_item, annmodel.SomeInstance) assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - def test_assert_type_is_list_doesnt_lose_info(self): - class T(object): - pass - def g(l): - assert type(l) is list - return l - def f(): - l = [T()] - return g(l) - a = self.RPythonAnnotator() - s = a.build_types(f, []) - s_item = listitem(s) - assert isinstance(s_item, annmodel.SomeInstance) - assert s_item.classdef is a.bookkeeper.getuniqueclassdef(T) - - def test_int_str_mul(self): def f(x,a,b): return a*x+x*b @@ -1395,11 +1344,10 @@ except KeyError: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.const = KeyError t.is_type_of = [ev] assert a.binding(et) == t @@ -1412,11 +1360,10 @@ except: raise a = self.RPythonAnnotator() - a.build_types(f, [dict]) + a.build_types(f, [somedict(annmodel.s_Int, annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t @@ -1448,11 +1395,10 @@ finally: h() a = self.RPythonAnnotator() - a.build_types(f, [int, list]) + a.build_types(f, [int, somelist(annmodel.s_Int)]) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) @@ -1474,24 +1420,11 @@ a.build_types(f, []) fg = graphof(a, f) et, ev = fg.exceptblock.inputargs - t = annmodel.SomeObject() - t.knowntype = type + t = annmodel.SomeType() t.is_type_of = [ev] assert a.binding(et) == t assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception) - def test_sys_attrs(self): - def f(): - return sys.argv[0] - a = self.RPythonAnnotator() - try: - oldvalue = sys.argv - sys.argv = [] - s = a.build_types(f, []) - finally: - sys.argv = oldvalue - assert s is not None - def test_pow(self): def f(n): n **= 2 @@ -1523,7 +1456,6 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int, str, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] def test_is_true_coalesce2(self): def f(a,b,a1,b1,c,d,e): @@ -1532,9 +1464,12 @@ return d,c return e,c a = self.RPythonAnnotator() - s = a.build_types(f, [int, str, float, list, a.bookkeeper.immutablevalue(1.0), a.bookkeeper.immutablevalue('d'), a.bookkeeper.immutablevalue('e')]) - assert s == annmodel.SomeTuple([annmodel.SomeChar(), a.bookkeeper.immutablevalue(1.0)]) - assert not [b for b in a.bindings.itervalues() if b.__class__ == annmodel.SomeObject] + s = a.build_types(f, [int, str, float, somelist(annmodel.s_Int), + a.bookkeeper.immutablevalue(1.0), + a.bookkeeper.immutablevalue('d'), + a.bookkeeper.immutablevalue('e')]) + assert s == annmodel.SomeTuple([annmodel.SomeChar(), + a.bookkeeper.immutablevalue(1.0)]) def test_is_true_coalesce_sanity(self): def f(a): @@ -1954,16 +1889,7 @@ t = type(x) return issubclass(t, A) - def f(): - x = g(1) - y = g(0) - return x or y - a = self.RPythonAnnotator() - s = a.build_types(f, []) - assert s.knowntype == bool - assert not s.is_constant() - a = self.RPythonAnnotator() - # sanity check + a = self.RPythonAnnotator() x = annmodel.SomeInteger() x.const = 1 s = a.build_types(g, [x]) @@ -2383,8 +2309,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [int]) - assert s.__class__ == annmodel.SomeObject - assert s.knowntype == type + assert isinstance(s, annmodel.SomeType) def test_annotate_iter_empty_container(self): def f(): diff --git a/pypy/annotation/test/test_model.py b/pypy/annotation/test/test_model.py --- a/pypy/annotation/test/test_model.py +++ b/pypy/annotation/test/test_model.py @@ -2,20 +2,19 @@ import autopath import py from pypy.annotation.model import * -from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF +from pypy.annotation.listdef import ListDef from pypy.rpython.ootypesystem.ootype import ROOT listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()])) listdef2 = ListDef(None, SomeTuple([SomeInteger(nonneg=False), SomeString()])) -s1 = SomeObject() s2 = SomeInteger(nonneg=True) s3 = SomeInteger(nonneg=False) s4 = SomeList(listdef1) s5 = SomeList(listdef2) s6 = SomeImpossibleValue() -slist = [s1,s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 +slist = [s2,s3,s4,s6] # not s5 -- unionof(s4,s5) modifies s4 and s5 class C(object): @@ -100,7 +99,8 @@ def test_list_contains(): listdef1 = ListDef(None, SomeInteger(nonneg=True)) s1 = SomeList(listdef1) - s2 = SomeList(MOST_GENERAL_LISTDEF) + listdef2 = ListDef(None, SomeInteger(nonneg=False)) + s2 = SomeList(listdef2) assert s1 != s2 assert s2.contains(s1) assert s1 != s2 diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py --- a/pypy/annotation/unaryop.py +++ b/pypy/annotation/unaryop.py @@ -7,7 +7,7 @@ SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ SomeDict, SomeTuple, SomeImpossibleValue, SomeUnicodeCodePoint, \ SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ - SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, SomeType, \ s_ImpossibleValue, s_Bool, s_None, \ unionof, missing_operation, add_knowntypedata, HarmlesslyBlocked, \ SomeGenericCallable, SomeWeakRef, SomeUnicodeString @@ -45,8 +45,7 @@ else: r = immutablevalue(obj.knowntype) else: - r = SomeObject() - r.knowntype = type + r = SomeType() bk = getbookkeeper() fn, block, i = bk.position_key annotator = bk.annotator diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py --- a/pypy/config/translationoption.py +++ b/pypy/config/translationoption.py @@ -129,8 +129,6 @@ # misc BoolOption("verbose", "Print extra information", default=False), - BoolOption("debug", "Record extra annotation information", - cmdline="-d --debug", default=True), BoolOption("insist", "Try hard to go on RTyping", default=False, cmdline="--insist"), StrOption("cc", "Specify compiler to use for compiling generated C", cmdline="--cc"), diff --git a/pypy/tool/error.py b/pypy/tool/error.py --- a/pypy/tool/error.py +++ b/pypy/tool/error.py @@ -72,6 +72,7 @@ pass def gather_error(annotator, block, graph): + XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX msg = [""] msg.append('-+' * 30) from pypy.annotation import model @@ -147,6 +148,7 @@ msg.append("") def format_someobject_error(annotator, position_key, what, s_value, called_from_graph, binding=""): + XXXXXXXXXXXXXXXXXXXXXX #block = getattr(annotator, 'flowin_block', None) or block msg = ["annotation of %r degenerated to SomeObject()" % (what,)] if position_key is not None: @@ -167,9 +169,6 @@ if called_from_graph is not None: msg.append(".. called from %r" % (called_from_graph,)) - if s_value.origin is not None: - msg.append(".. SomeObject() origin: %s" % ( - annotator.whereami(s_value.origin),)) msg.append("Previous annotation:") msg.append(" " + str(binding)) return "\n".join(msg) diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py --- a/pypy/translator/driver.py +++ b/pypy/translator/driver.py @@ -309,7 +309,6 @@ policy = self.policy self.log.info('with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__)) - annmodel.DEBUG = self.config.translation.debug annotator = translator.buildannotator(policy=policy) if self.secondary_entrypoints is not None: diff --git a/pypy/translator/test/snippet.py b/pypy/translator/test/snippet.py --- a/pypy/translator/test/snippet.py +++ b/pypy/translator/test/snippet.py @@ -522,9 +522,10 @@ def methodcall_is_precise(cond): if cond: x = CSub1() + x.m() else: x = CSub2() - x.m() + x.m() return CSub1().m() @@ -541,18 +542,6 @@ else: return WithMoreInit(1, 2) -def flow_identity_info(x=object, y=object): - if x is None: - if y is None: - return (x, y) - else: - return (x, None) - else: - if y is None: - return (None, y) - else: - return (None, None) - def star_args0(*args): return args[0] / 2 @@ -658,13 +647,6 @@ break return v -def _inheritance_nonrunnable(): - d = D() - d.stuff = (-12, -12) - e = E() - e.stuff = (3, "world") - return C().stuff - def _getstuff(x): return x.stuff @@ -788,7 +770,7 @@ def dict_keys2(): d = {"a" : 1} keys = d.keys() - d[1] = 12 + d["123"] = 12 return keys def dict_values(): @@ -796,9 +778,9 @@ return d.values() def dict_values2(): - d = {"a" : "a"} + d = {54312 : "a"} values = d.values() - d[1] = 12 + d[1] = "12" return values def dict_items(): @@ -942,94 +924,6 @@ return fn(n) -class BltinCode: - def __init__(self, func, framecls): - self.func = func - self.framecls = framecls - - def call(self, x): - return self.framecls(self).run(x) - -class BltinFrame: - def __init__(self, code): - self.code = code - -def bltin_code_frame_f(x): - return x - -def bltin_code_frame_g(x): - return x - -class FBltinFrame(BltinFrame): - - def run(self, x): - return self.code.func(x) - -class GBltinFrame(BltinFrame): - - def run(self, x): - return self.code.func(x) - -bltin_code_for_f = BltinCode(bltin_code_frame_f, FBltinFrame) -bltin_code_for_g = BltinCode(bltin_code_frame_g, GBltinFrame) - -def bltin_code_frame_confusion(): - a = bltin_code_for_f.call(0) - a1 = bltin_code_for_f.call(1) - b = bltin_code_for_g.call("a") - b1 = bltin_code_for_g.call("b") - return (a,a1,b,b1) - - -# reorg - -class BltinCodeReorg: - def __init__(self, framecls): - self.framecls = framecls - - def call(self, x): - frame = self.framecls() - frame.set(x) - return frame.run() - -class BltinFrameReorg: - def __init__(self): - pass - - def set(self,x): - pass - - def run(self): - pass - -class FBltinFrameReorg(BltinFrameReorg): - - def set(self, x): - self.arg = int(x) - - def run(self): - return bltin_code_frame_f(self.arg) - -class GBltinFrameReorg(BltinFrameReorg): - - def set(self, x): - self.arg = str(x) - - def run(self): - return bltin_code_frame_g(self.arg) - - -bltin_code_for_f_reorg = BltinCodeReorg(FBltinFrameReorg) -bltin_code_for_g_reorg = BltinCodeReorg(GBltinFrameReorg) - -def bltin_code_frame_reorg(): - a = bltin_code_for_f_reorg.call(0) - a1 = bltin_code_for_f_reorg.call(1) - b = bltin_code_for_g_reorg.call("a") - b1 = bltin_code_for_g_reorg.call("b") - return (a,a1,b,b1) - - # constant instances with __init__ vs. __new__ class Thing1: diff --git a/pypy/translator/tool/graphpage.py b/pypy/translator/tool/graphpage.py --- a/pypy/translator/tool/graphpage.py +++ b/pypy/translator/tool/graphpage.py @@ -27,9 +27,6 @@ label += "\\n" + self.createlink(info.origin, 'Originated at') if caused_by is not None: label += '\\n' + self.createlink(caused_by) - if info.caused_by_merge is not None: - data = 'unionof%r' % (info.caused_by_merge,) - label += '\\n%s' % nottoowide(data) dotgen.emit_node('0', shape="box", color="red", label=label) for n, (data, caused_by) in zip(range(len(history)), history): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit