def newtuple(self, items_s): if items_s == [Ellipsis]: res = SomeObject() # hack to get a SomeObject as the *arg res.from_ellipsis = True return res else: return SomeTuple(items_s)
def _compute_annotation(t, bookkeeper=None): from pypy.rpython.lltypesystem import lltype from pypy.rpython import extregistry if isinstance(t, SomeObject): return t elif isinstance(t, lltype.LowLevelType): return lltype_to_annotation(t) elif isinstance(t, list): assert len(t) == 1, "We do not support type joining in list" listdef = ListDef(bookkeeper, annotation(t[0]), mutated=True, resized=True) return SomeList(listdef) elif isinstance(t, tuple): return SomeTuple(tuple([annotation(i) for i in t])) elif isinstance(t, dict): assert len(t) == 1, "We do not support type joining in dict" result = SomeDict( DictDef(bookkeeper, annotation(t.keys()[0]), annotation(t.values()[0]))) return result elif type(t) is types.NoneType: return s_None elif extregistry.is_registered(t): entry = extregistry.lookup(t) entry.bookkeeper = bookkeeper return entry.compute_result_annotation() else: return annotationoftype(t, bookkeeper)
def newtuple(self, items_s): if len(items_s) == 1 and items_s[0] is Ellipsis: res = SomeObject() # hack to get a SomeObject as the *arg res.from_ellipsis = True return res else: return SomeTuple(items_s)
def getattr(s_array, s_attr): s = None if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const if attr == 'shape': s = SomeTuple([SomeInteger()] * s_array.ndim) elif attr == 'ndim': s = SomeInteger() elif attr == 'dtype': s = SomeChar() if s is None: return SomeObject.getattr(s_array, s_attr) return s
def getanyitem(dct, variant='keys'): if variant == 'keys': return dct.dictdef.read_key() elif variant == 'values': return dct.dictdef.read_value() elif variant == 'items': s_key = dct.dictdef.read_key() s_value = dct.dictdef.read_value() if (isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue)): return s_ImpossibleValue else: return SomeTuple((s_key, s_value)) else: raise ValueError
def builtin_zip(s_iterable1, s_iterable2): # xxx not actually implemented s_iter1 = s_iterable1.iter() s_iter2 = s_iterable2.iter() s_tup = SomeTuple((s_iter1.next(),s_iter2.next())) return getbookkeeper().newlist(s_tup)
def next(itr): if itr.variant == ("enumerate", ): s_item = itr.s_container.getanyitem() return SomeTuple((SomeInteger(nonneg=True), s_item)) return itr.s_container.getanyitem(*itr.variant)
def getslice(tup, s_start, s_stop): assert s_start.is_immutable_constant( ), "tuple slicing: needs constants" assert s_stop.is_immutable_constant(), "tuple slicing: needs constants" items = tup.items[s_start.const:s_stop.const] return SomeTuple(items)
result = getattr(self.obj, '__dict__', {}).keys() tp = self.obj.__class__ if isinstance(tp, type): for basetype in tp.__mro__: slots = basetype.__dict__.get('__slots__') if slots: if isinstance(slots, str): result.append(slots) else: result.extend(slots) return result class NoSuchAttrError(Exception): """Raised when an attribute is found on a class where __slots__ or _attrs_ forbits it.""" # ____________________________________________________________ FORCE_ATTRIBUTES_INTO_CLASSES = { OSError: {'errno': SomeInteger()}, } try: import termios except ImportError: pass else: FORCE_ATTRIBUTES_INTO_CLASSES[termios.error] = \ {'args': SomeTuple([SomeInteger(), SomeString()])}
def union((tup1, tup2)): if len(tup1.items) != len(tup2.items): return SomeObject() else: unions = [unioncheck(x, y) for x, y in zip(tup1.items, tup2.items)] return SomeTuple(items=unions)
def divmod((obj1, obj2)): getbookkeeper().count("divmod", obj1, obj2) return SomeTuple([pair(obj1, obj2).div(), pair(obj1, obj2).mod()])
def getitem((s_array, s_index)): s_tuple = SomeTuple([s_index]) return pair(s_array, s_tuple).getitem()
class __extend__(pairtype(SomeArray, SomeInteger)): def setitem((s_array, s_index), s_value): s_tuple = SomeTuple([s_index]) return pair(s_array, s_tuple).setitem(s_value)
def register_os_utime(self): UTIMBUFP = lltype.Ptr(self.UTIMBUF) os_utime = self.llexternal('utime', [rffi.CCHARP, UTIMBUFP], rffi.INT) class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=['sys/time.h'] ) HAVE_UTIMES = platform.Has('utimes') config = platform.configure(CConfig) if config['HAVE_UTIMES']: class CConfig: _compilation_info_ = ExternalCompilationInfo( includes = ['sys/time.h'] ) TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG)]) config = platform.configure(CConfig) TIMEVAL = config['TIMEVAL'] TIMEVAL2P = rffi.CArrayPtr(TIMEVAL) os_utimes = self.llexternal('utimes', [rffi.CCHARP, TIMEVAL2P], rffi.INT, compilation_info=CConfig._compilation_info_) def os_utime_platform(path, actime, modtime): import math l_times = lltype.malloc(TIMEVAL2P.TO, 2, flavor='raw') fracpart, intpart = math.modf(actime) l_times[0].c_tv_sec = int(intpart) l_times[0].c_tv_usec = int(fracpart * 1E6) fracpart, intpart = math.modf(modtime) l_times[1].c_tv_sec = int(intpart) l_times[1].c_tv_usec = int(fracpart * 1E6) error = os_utimes(path, l_times) lltype.free(l_times, flavor='raw') return error else: # we only have utime(), which does not allow sub-second resolution def os_utime_platform(path, actime, modtime): l_utimbuf = lltype.malloc(UTIMBUFP.TO, flavor='raw') l_utimbuf.c_actime = int(actime) l_utimbuf.c_modtime = int(modtime) error = os_utime(path, l_utimbuf) lltype.free(l_utimbuf, flavor='raw') return error def os_utime_llimpl(path, tp): # NB. this function is specialized; we get one version where # tp is known to be None, and one version where it is known # to be a tuple of 2 floats. if tp is None: error = os_utime(path, lltype.nullptr(UTIMBUFP.TO)) else: actime, modtime = tp error = os_utime_platform(path, actime, modtime) error = rffi.cast(lltype.Signed, error) if error == -1: raise OSError(rposix.get_errno(), "os_utime failed") os_utime_llimpl._annspecialcase_ = 'specialize:argtype(1)' s_string = SomeString() s_tuple_of_2_floats = SomeTuple([SomeFloat(), SomeFloat()]) def os_utime_normalize_args(s_path, s_times): # special handling of the arguments: they can be either # [str, (float, float)] or [str, s_None], and get normalized # to exactly one of these two. if not s_string.contains(s_path): raise Exception("os.utime() arg 1 must be a string, got %s" % ( s_path,)) case1 = s_None.contains(s_times) case2 = s_tuple_of_2_floats.contains(s_times) if case1 and case2: return [s_string, s_ImpossibleValue] #don't know which case yet elif case1: return [s_string, s_None] elif case2: return [s_string, s_tuple_of_2_floats] else: raise Exception("os.utime() arg 2 must be None or a tuple of " "2 floats, got %s" % (s_times,)) return extdef(os_utime_normalize_args, s_None, "ll_os.ll_os_utime", llimpl=os_utime_llimpl)
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
def add((tup1, tup2)): return SomeTuple(items=tup1.items + tup2.items)
def getitem((tup, slic)): start, stop, step = slic.constant_indices() return SomeTuple(tup.items[start:stop:step])