Exemple #1
0
 def type(obj, *moreargs):
     if moreargs:
         raise Exception, 'type() called with more than one argument'
     if obj.is_constant():
         if isinstance(obj, SomeInstance):
             r = SomePBC([obj.classdef.classdesc])
         else:
             r = immutablevalue(obj.knowntype)
     else:
         r = SomeObject()
         r.knowntype = type
     bk = getbookkeeper()
     fn, block, i = bk.position_key
     annotator = bk.annotator
     op = block.operations[i]
     assert op.opname == "type"
     assert len(op.args) == 1
     assert annotator.binding(op.args[0]) == obj
     r.is_type_of = [op.args[0]]
     return r
Exemple #2
0
 def type(obj, *moreargs):
     if moreargs:
         raise Exception, "type() called with more than one argument"
     if obj.is_constant():
         if isinstance(obj, SomeInstance):
             r = SomePBC([obj.classdef.classdesc])
         else:
             r = immutablevalue(obj.knowntype)
     else:
         r = SomeObject()
         r.knowntype = type
     bk = getbookkeeper()
     fn, block, i = bk.position_key
     annotator = bk.annotator
     op = block.operations[i]
     assert op.opname == "type"
     assert len(op.args) == 1
     assert annotator.binding(op.args[0]) == obj
     r.is_type_of = [op.args[0]]
     return r
Exemple #3
0
 def s_get_value(self, classdef, name):
     obj = self.classdict[name]
     if isinstance(obj, Constant):
         value = obj.value
         if isinstance(value, staticmethod):  # special case
             value = value.__get__(42)
             classdef = None  # don't bind
         s_value = self.bookkeeper.immutablevalue(value)
         if classdef is not None:
             s_value = s_value.bind_callables_under(classdef, name)
     elif isinstance(obj, Desc):
         from pypy.annotation.model import SomePBC
         if classdef is not None:
             obj = obj.bind_under(classdef, name)
         s_value = SomePBC([obj])
     else:
         raise TypeError("classdict should not contain %r" % (obj, ))
     return s_value
Exemple #4
0
    def lookup_filter(self, pbc, name=None, flags={}):
        """Selects the methods in the pbc that could possibly be seen by
        a lookup performed on an instance of 'self', removing the ones
        that cannot appear.
        """
        d = []
        uplookup = None
        updesc = None
        meth = False
        check_for_missing_attrs = False
        for desc in pbc.descriptions:
            # pick methods but ignore already-bound methods, which can come
            # from an instance attribute
            if (isinstance(desc, description.MethodDesc)
                and desc.selfclassdef is None):
                meth = True
                methclassdef = desc.originclassdef
                if methclassdef is not self and methclassdef.issubclass(self):
                    pass # subclasses methods are always candidates
                elif self.issubclass(methclassdef):
                    # upward consider only the best match
                    if uplookup is None or methclassdef.issubclass(uplookup):
                        uplookup = methclassdef
                        updesc = desc
                    continue
                    # for clsdef1 >= clsdef2, we guarantee that
                    # clsdef1.lookup_filter(pbc) includes
                    # clsdef2.lookup_filter(pbc) (see formal proof...)
                else:
                    continue # not matching
                # bind the method by giving it a selfclassdef.  Use the
                # more precise subclass that it's coming from.
                desc = desc.bind_self(methclassdef, flags)
            d.append(desc)
        if uplookup is not None:            
            d.append(updesc.bind_self(self, flags))

        if d or pbc.can_be_None:
            return SomePBC(d, can_be_None=pbc.can_be_None)
        else:
            return s_ImpossibleValue
Exemple #5
0
 def pycall(self, schedule, args, s_previous_result, op=None):
     from pypy.annotation.model import SomePBC
     s_self = SomePBC([self.frozendesc])
     args = args.prepend(s_self)
     return self.funcdesc.pycall(schedule, args, s_previous_result, op)
Exemple #6
0
 def immutablevalue(self, x, need_const=True):
     """The most precise SomeValue instance that contains the
     immutable value x."""
     # convert unbound methods to the underlying function
     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()
         result.const_box = Constant(x)
         return result
     if tp is bool:
         result = SomeBool()
     elif tp is int:
         result = SomeInteger(nonneg=x >= 0)
     elif tp is long:
         if -sys.maxint - 1 <= x <= sys.maxint:
             x = int(x)
             result = SomeInteger(nonneg=x >= 0)
         else:
             raise Exception("seeing a prebuilt long (value %s)" % hex(x))
     elif issubclass(tp, str):  # py.lib uses annotated str subclasses
         if len(x) == 1:
             result = SomeChar()
         else:
             result = SomeString()
     elif tp is unicode:
         if len(x) == 1:
             result = SomeUnicodeCodePoint()
         else:
             result = SomeUnicodeString()
     elif tp is tuple:
         result = SomeTuple(
             items=[self.immutablevalue(e, need_const) for e in x])
     elif tp is float:
         result = SomeFloat()
     elif tp is list:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeList(ListDef(self, s_ImpossibleValue))
                 self.immutable_cache[key] = result
                 for e in x:
                     result.listdef.generalize(self.immutablevalue(e))
                 result.const_box = key
                 return result
         else:
             listdef = ListDef(self, s_ImpossibleValue)
             for e in x:
                 listdef.generalize(self.immutablevalue(e, False))
             result = SomeList(listdef)
     elif tp is dict or tp is r_dict:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeDict(
                     DictDef(self,
                             s_ImpossibleValue,
                             s_ImpossibleValue,
                             is_r_dict=tp is r_dict))
                 self.immutable_cache[key] = result
                 if tp is r_dict:
                     s_eqfn = self.immutablevalue(x.key_eq)
                     s_hashfn = self.immutablevalue(x.key_hash)
                     result.dictdef.dictkey.update_rdict_annotations(
                         s_eqfn, s_hashfn)
                 seen_elements = 0
                 while seen_elements != len(x):
                     items = x.items()
                     for ek, ev in items:
                         result.dictdef.generalize_key(
                             self.immutablevalue(ek))
                         result.dictdef.generalize_value(
                             self.immutablevalue(ev))
                         result.dictdef.seen_prebuilt_key(ek)
                     seen_elements = len(items)
                     # if the dictionary grew during the iteration,
                     # start over again
                 result.const_box = key
                 return result
         else:
             dictdef = DictDef(self,
                               s_ImpossibleValue,
                               s_ImpossibleValue,
                               is_r_dict=tp is r_dict)
             if tp is r_dict:
                 s_eqfn = self.immutablevalue(x.key_eq)
                 s_hashfn = self.immutablevalue(x.key_hash)
                 dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
             for ek, ev in x.iteritems():
                 dictdef.generalize_key(self.immutablevalue(ek, False))
                 dictdef.generalize_value(self.immutablevalue(ev, False))
                 dictdef.seen_prebuilt_key(ek)
             result = SomeDict(dictdef)
     elif tp is weakref.ReferenceType:
         x1 = x()
         if x1 is None:
             result = SomeWeakRef(None)  # dead weakref
         else:
             s1 = self.immutablevalue(x1)
             assert isinstance(s1, SomeInstance)
             result = SomeWeakRef(s1.classdef)
     elif ishashable(x) and x in BUILTIN_ANALYZERS:
         _module = getattr(x, "__module__", "unknown")
         result = SomeBuiltin(BUILTIN_ANALYZERS[x],
                              methodname="%s.%s" % (_module, x.__name__))
     elif extregistry.is_registered(x, self.policy):
         entry = extregistry.lookup(x, self.policy)
         result = entry.compute_annotation_bk(self)
     elif isinstance(x, lltype._ptr):
         result = SomePtr(lltype.typeOf(x))
     elif isinstance(x, llmemory.fakeaddress):
         result = SomeAddress()
     elif isinstance(x, ootype._static_meth):
         result = SomeOOStaticMeth(ootype.typeOf(x))
     elif isinstance(x, ootype._class):
         result = SomeOOClass(x._INSTANCE)  # NB. can be None
     elif isinstance(x, ootype.instance_impl):  # XXX
         result = SomeOOInstance(ootype.typeOf(x))
     elif isinstance(x, (ootype._record, ootype._string)):
         result = SomeOOInstance(ootype.typeOf(x))
     elif isinstance(x, (ootype._object)):
         result = SomeOOObject()
     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
             # global constant list, the find_method() returns non-None
             s_self = self.immutablevalue(x.im_self, need_const)
             result = s_self.find_method(x.im_func.__name__)
         elif hasattr(x, '__self__') and x.__self__ is not None:
             # 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()
         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)])
     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
         # returns True, the instance is considered immutable and becomes
         # a SomePBC().  Otherwise it's just SomeInstance().
         result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '__class__') \
              and x.__class__.__module__ != '__builtin__':
         self.see_mutable(x)
         result = SomeInstance(self.getuniqueclassdef(x.__class__))
     elif x is None:
         return s_None
     else:
         result = SomeObject()
     if need_const:
         result.const = x
     return result
Exemple #7
0
 def bind_callables_under(pbc, classdef, name):
     d = [desc.bind_under(classdef, name) for desc in pbc.descriptions]
     return SomePBC(d, can_be_None=pbc.can_be_None)
Exemple #8
0
 def union((pbc1, pbc2)):
     d = pbc1.descriptions.copy()
     d.update(pbc2.descriptions)
     return SomePBC(d, can_be_None=pbc1.can_be_None or pbc2.can_be_None)
Exemple #9
0
 def read_attr__class__(self):
     position = self.bookkeeper.position_key
     self.read_locations_of__class__[position] = True
     return SomePBC([subdef.classdesc for subdef in self.getallsubdefs()])