def test_pairmro(): class A(object): pass class A2(A): pass class A3(A2): pass class B(object): pass class B2(B): pass parent_pairtypes = pairtype(A3, B2).__mro__[:-2] assert (tuple(pairtype(a, b) for a, b in pairmro(A3, B2)) == parent_pairtypes)
def is_((pbc1, pbc2)): thistype = pairtype(SomePBC, SomePBC) s = super(thistype, pair(pbc1, pbc2)).is_() if not s.is_constant(): if not pbc1.can_be_None or not pbc2.can_be_None: for desc in pbc1.descriptions: if desc in pbc2.descriptions: break else: s.const = False # no common desc in the two sets return s
class __extend__(pairtype(SomeList, SomeList)): def union((lst1, lst2)): return SomeList(lst1.listdef.union(lst2.listdef)) def add((lst1, lst2)): bk = getbookkeeper() return lst1.listdef.offspring(bk, lst2.listdef) def eq((lst1, lst2)): lst1.listdef.agree(getbookkeeper(), lst2.listdef) return s_Bool ne = eq
class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): return SomeChar(no_nul=str1.no_nul) getitem.can_only_throw = [] def getitem_idx((str1, int2)): return SomeChar(no_nul=str1.no_nul) getitem_idx.can_only_throw = [IndexError] def mul((str1, int2)): # xxx do we want to support this return SomeString(no_nul=str1.no_nul)
class __extend__(pairtype(SomeUnicodeString, SomeInteger)): def getitem((str1, int2)): return SomeUnicodeCodePoint() getitem.can_only_throw = [] def getitem_idx((str1, int2)): return SomeUnicodeCodePoint() getitem_idx.can_only_throw = [IndexError] def mul((str1, int2)): # xxx do we want to support this return SomeUnicodeString()
class __extend__(pairtype(AbstractListRepr, AbstractStringRepr)): def rtype_inplace_add((r_lst1, r_str2), hop): if r_lst1.item_repr.lowleveltype not in (Char, UniChar): raise TyperError('"lst += string" only supported with a list ' 'of chars or unichars') string_repr = r_str2.repr v_lst1, v_str2 = hop.inputargs(r_lst1, string_repr) c_strlen = hop.inputconst(Void, string_repr.ll.ll_strlen) c_stritem = hop.inputconst(Void, string_repr.ll.ll_stritem_nonneg) if hop.unsafe: llfn = ll_extend_with_str_unsafe else: llfn = ll_extend_with_str hop.gendirectcall(llfn, v_lst1, v_str2, c_strlen, c_stritem) return v_lst1
class __extend__(pairtype(SomeString, SomeString)): def union((str1, str2)): can_be_None = str1.can_be_None or str2.can_be_None no_nul = str1.no_nul and str2.no_nul return SomeString(can_be_None=can_be_None, no_nul=no_nul) def add((str1, str2)): # propagate const-ness to help getattr(obj, 'prefix' + const_name) result = SomeString(no_nul=str1.no_nul and str2.no_nul) if str1.is_immutable_constant() and str2.is_immutable_constant(): result.const = str1.const + str2.const return result
class __extend__(pairtype(DictRepr, DictRepr)): def convert_from_to((r_dict1, r_dict2), v, llops): # check that we don't convert from Dicts with # different key/value types if r_dict1.dictkey is None or r_dict2.dictkey is None: return NotImplemented if r_dict1.dictkey is not r_dict2.dictkey: return NotImplemented if r_dict1.dictvalue is None or r_dict2.dictvalue is None: return NotImplemented if r_dict1.dictvalue is not r_dict2.dictvalue: return NotImplemented return v
class __extend__(pairtype(FloatRepr, FloatRepr)): #Arithmetic def rtype_add(_, hop): return _rtype_template(hop, 'add') rtype_inplace_add = rtype_add def rtype_sub(_, hop): return _rtype_template(hop, 'sub') rtype_inplace_sub = rtype_sub def rtype_mul(_, hop): return _rtype_template(hop, 'mul') rtype_inplace_mul = rtype_mul def rtype_truediv(_, hop): return _rtype_template(hop, 'truediv') rtype_inplace_truediv = rtype_truediv # turn 'div' on floats into 'truediv' rtype_div = rtype_truediv rtype_inplace_div = rtype_inplace_truediv # 'floordiv' on floats not supported in RPython #comparisons: eq is_ ne lt le gt ge def rtype_eq(_, hop): return _rtype_compare_template(hop, 'eq') rtype_is_ = rtype_eq def rtype_ne(_, hop): return _rtype_compare_template(hop, 'ne') def rtype_lt(_, hop): return _rtype_compare_template(hop, 'lt') def rtype_le(_, hop): return _rtype_compare_template(hop, 'le') def rtype_gt(_, hop): return _rtype_compare_template(hop, 'gt') def rtype_ge(_, hop): return _rtype_compare_template(hop, 'ge')
class __extend__(pairtype(IntegerRepr, IntegerRepr)): def convert_from_to((r_from, r_to), v, llops): if r_from.lowleveltype == Signed and r_to.lowleveltype == Unsigned: log.debug('explicit cast_int_to_uint') return llops.genop('cast_int_to_uint', [v], resulttype=Unsigned) if r_from.lowleveltype == Unsigned and r_to.lowleveltype == Signed: log.debug('explicit cast_uint_to_int') return llops.genop('cast_uint_to_int', [v], resulttype=Signed) if r_from.lowleveltype == Signed and r_to.lowleveltype == SignedLongLong: return llops.genop('cast_int_to_longlong', [v], resulttype=SignedLongLong) if r_from.lowleveltype == SignedLongLong and r_to.lowleveltype == Signed: return llops.genop('truncate_longlong_to_int', [v], resulttype=Signed) return llops.genop('cast_primitive', [v], resulttype=r_to.lowleveltype)
class __extend__(pairtype(FunctionReprBase, FunctionReprBase)): def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) s_pbc = annmodel.unionof(robj1.s_pbc, robj2.s_pbc) r_pbc = hop.rtyper.getrepr(s_pbc) v1, v2 = hop.inputargs(r_pbc, r_pbc) assert v1.concretetype == v2.concretetype if v1.concretetype == Char: return hop.genop('char_eq', [v1, v2], resulttype=Bool) elif isinstance(v1.concretetype, Ptr): return hop.genop('ptr_eq', [v1, v2], resulttype=Bool) else: raise TyperError("unknown type %r" % (v1.concretetype, ))
class __extend__(pairtype(AbstractListRepr, IntegerRepr)): def rtype_delitem((r_lst, r_int), hop): if hop.has_implicit_exception(IndexError): spec = dum_checkidx else: spec = dum_nocheck v_func = hop.inputconst(Void, spec) v_lst, v_index = hop.inputargs(r_lst, Signed) if hop.args_s[1].nonneg: llfn = ll_delitem_nonneg else: llfn = ll_delitem hop.exception_is_here() return hop.gendirectcall(llfn, v_func, v_lst, v_index)
class __extend__(pairtype(SomeFloat, SomeFloat)): def union((flt1, flt2)): return SomeFloat() add = sub = mul = union def div((flt1, flt2)): return SomeFloat() div.can_only_throw = [] truediv = div # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv
class __extend__(pairtype(FloatRepr, IntegerRepr)): def convert_from_to((r_from, r_to), v, llops): if r_from.lowleveltype == Float and r_to.lowleveltype == Unsigned: log.debug('explicit cast_float_to_uint') return llops.genop('cast_float_to_uint', [v], resulttype=Unsigned) if r_from.lowleveltype == Float and r_to.lowleveltype == Signed: log.debug('explicit cast_float_to_int') return llops.genop('cast_float_to_int', [v], resulttype=Signed) if r_from.lowleveltype == Float and r_to.lowleveltype == SignedLongLong: log.debug('explicit cast_float_to_longlong') return llops.genop('cast_float_to_longlong', [v], resulttype=SignedLongLong) if r_from.lowleveltype == Float and r_to.lowleveltype == UnsignedLongLong: log.debug('explicit cast_float_to_ulonglong') return llops.genop('cast_float_to_ulonglong', [v], resulttype=UnsignedLongLong) return NotImplemented
class __extend__(pairtype(SomeOOInstance, SomeInteger)): def getitem((ooinst, index)): if ooinst.ootype._isArray: return SomeOOInstance(ooinst.ootype._ELEMENT) return s_ImpossibleValue def setitem((ooinst, index), s_value): if ooinst.ootype._isArray: if s_value is annmodel.s_None: return s_None ELEMENT = ooinst.ootype._ELEMENT VALUE = s_value.ootype assert ootype.isSubclass(VALUE, ELEMENT) return s_None return s_ImpossibleValue
class __extend__(pairtype(SomeDict, SomeObject)): def _can_only_throw(dic1, *ignore): if dic1.dictdef.dictkey.custom_eq_hash: return None return [KeyError] def getitem((dic1, obj2)): dic1.dictdef.generalize_key(obj2) return dic1.dictdef.read_value() getitem.can_only_throw = _can_only_throw def setitem((dic1, obj2), s_value): dic1.dictdef.generalize_key(obj2) dic1.dictdef.generalize_value(s_value)
class __extend__(pairtype(SomeInstance, SomeInstance)): def union((ins1, ins2)): if ins1.classdef is None or ins2.classdef is None: # special case only basedef = None else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: print "\n\nUnionError will be thrown, basically there are 2 or more classes that are on a same context (variable, function args, or function return) that aren't compatible. Here are their __dict__:" print '\n', ins1.classdef.classdesc.classdict print '\n', ins2.classdef.classdesc.classdict, '\n' raise UnionError(ins1, ins2, "RPython cannot unify instances " "with no common base class") flags = ins1.flags if flags: flags = flags.copy() for key, value in flags.items(): if key not in ins2.flags or ins2.flags[key] != value: del flags[key] return SomeInstance(basedef, can_be_None=ins1.can_be_None or ins2.can_be_None, flags=flags) def improve((ins1, ins2)): if ins1.classdef is None: resdef = ins2.classdef elif ins2.classdef is None: resdef = ins1.classdef else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is ins1.classdef: resdef = ins2.classdef elif basedef is ins2.classdef: resdef = ins1.classdef else: if ins1.can_be_None and ins2.can_be_None: return s_None else: return s_ImpossibleValue res = SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) if ins1.contains(res) and ins2.contains(res): return res # fine else: # this case can occur in the presence of 'const' attributes, # which we should try to preserve. Fall-back... thistype = pairtype(SomeInstance, SomeInstance) return super(thistype, pair(ins1, ins2)).improve()
class __extend__(pairtype(SomePtr, SomeInteger)): def getitem((p, int1)): example = p.ll_ptrtype._example() try: v = example[0] except IndexError: return None # impossible value, e.g. FixedSizeArray(0) return ll_to_annotation(v) getitem.can_only_throw = [] def setitem((p, int1), s_value): # just doing checking example = p.ll_ptrtype._example() if example[0] is not None: # ignore Void s_value v_lltype = annotation_to_lltype(s_value) example[0] = v_lltype._defl()
class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() def inplace_sub((obj1, obj2)): return pair(obj1, obj2).sub() def inplace_mul((obj1, obj2)): return pair(obj1, obj2).mul() def inplace_truediv((obj1, obj2)): return pair(obj1, obj2).truediv() def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift() def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift() def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_() def inplace_or((obj1, obj2)): return pair(obj1, obj2).or_() def inplace_xor((obj1, obj2)): return pair(obj1, obj2).xor() for name, func in locals().items(): if name.startswith('inplace_'): func.can_only_throw = [] inplace_div.can_only_throw = [ZeroDivisionError] inplace_truediv.can_only_throw = [ZeroDivisionError] inplace_floordiv.can_only_throw = [ZeroDivisionError] inplace_mod.can_only_throw = [ZeroDivisionError] def cmp((obj1, obj2)): if obj1.is_immutable_constant() and obj2.is_immutable_constant(): return immutablevalue(cmp(obj1.const, obj2.const)) else: return SomeInteger() def divmod((obj1, obj2)): return SomeTuple([pair(obj1, obj2).div(), pair(obj1, obj2).mod()]) def coerce((obj1, obj2)): return pair(obj1, obj2).union() # reasonable enough def add((obj1, obj2)): return s_ImpossibleValue sub = mul = truediv = floordiv = div = mod = add lshift = rshift = and_ = or_ = xor = delitem = add def setitem((obj1, obj2), _): return s_ImpossibleValue
class __extend__(pairtype(SomeInstance, SomeInstance)): def union((ins1, ins2)): if ins1.classdef is None or ins2.classdef is None: # special case only basedef = None else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is None: raise UnionError( ins1, ins2, "RPython cannot unify instances " "with no common base class") flags = ins1.flags if flags: flags = flags.copy() for key, value in flags.items(): if key not in ins2.flags or ins2.flags[key] != value: del flags[key] return SomeInstance(basedef, can_be_None=ins1.can_be_None or ins2.can_be_None, flags=flags) def improve((ins1, ins2)): if ins1.classdef is None: resdef = ins2.classdef elif ins2.classdef is None: resdef = ins1.classdef else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is ins1.classdef: resdef = ins2.classdef elif basedef is ins2.classdef: resdef = ins1.classdef else: if ins1.can_be_None and ins2.can_be_None: return s_None else: return s_ImpossibleValue res = SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) if ins1.contains(res) and ins2.contains(res): return res # fine else: # this case can occur in the presence of 'const' attributes, # which we should try to preserve. Fall-back... thistype = pairtype(SomeInstance, SomeInstance) return super(thistype, pair(ins1, ins2)).improve()
class __extend__(pairtype(SomeList, SomeInteger)): def mul((lst1, int2)): return lst1.listdef.offspring() def getitem((lst1, int2)): return lst1.listdef.read_item() getitem.can_only_throw = [] def getitem_idx((lst1, int2)): return lst1.listdef.read_item() getitem_idx.can_only_throw = [IndexError] def setitem((lst1, int2), s_value): lst1.listdef.mutate() lst1.listdef.generalize(s_value)
class __extend__(pairtype(AbstractRangeRepr, IntegerRepr)): def rtype_getitem((r_rng, r_int), hop): if hop.has_implicit_exception(IndexError): spec = dum_checkidx else: spec = dum_nocheck v_func = hop.inputconst(Void, spec) v_lst, v_index = hop.inputargs(r_rng, Signed) if r_rng.step != 0: cstep = hop.inputconst(Signed, r_rng.step) else: cstep = r_rng._getstep(v_lst, hop) if hop.args_s[1].nonneg: llfn = ll_rangeitem_nonneg else: llfn = ll_rangeitem hop.exception_is_here() return hop.gendirectcall(llfn, v_func, v_lst, v_index, cstep)
class __extend__(pairtype(AbstractUniCharRepr, AbstractUniCharRepr)): def rtype_eq(_, hop): return _rtype_unchr_compare_template(hop, 'eq') def rtype_ne(_, hop): return _rtype_unchr_compare_template(hop, 'ne') def rtype_lt(_, hop): return _rtype_unchr_compare_template_ord(hop, 'lt') def rtype_le(_, hop): return _rtype_unchr_compare_template_ord(hop, 'le') def rtype_gt(_, hop): return _rtype_unchr_compare_template_ord(hop, 'gt') def rtype_ge(_, hop): return _rtype_unchr_compare_template_ord(hop, 'ge')
class __extend__(pairtype(MTag, annmodel.SomeDict)): def install_marshaller((tag, s_dict)): def dump_dict_or_none(buf, x): if x is None: dump_none(buf, x) else: buf.append(TYPE_DICT) for key, value in x.items(): keydumper(buf, key) valuedumper(buf, value) buf.append('0') # end of dict keydumper = get_marshaller(s_dict.dictdef.dictkey.s_value) valuedumper = get_marshaller(s_dict.dictdef.dictvalue.s_value) if (s_dict.dictdef.dictkey.dont_change_any_more or s_dict.dictdef.dictvalue.dont_change_any_more): s_general_dict = s_dict else: s_key = get_dumper_annotation(keydumper) s_value = get_dumper_annotation(valuedumper) s_general_dict = annotation({s_key: s_value}) add_dumper(s_general_dict, dump_dict_or_none) def install_unmarshaller((tag, s_dict)): def load_dict_or_none(loader): t = readchr(loader) if t == TYPE_DICT: result = {} while peekchr(loader) != '0': key = keyloader(loader) value = valueloader(loader) result[key] = value readchr(loader) # consume the final '0' return result elif t == TYPE_NONE: return None else: raise ValueError("expected a dict or None") keyloader = get_loader(s_dict.dictdef.dictkey.s_value) valueloader = get_loader(s_dict.dictdef.dictvalue.s_value) add_loader(s_dict, load_dict_or_none)
class __extend__(pairtype(InstanceRepr, InstanceRepr)): def convert_from_to((r_ins1, r_ins2), v, llops): # which is a subclass of which? if r_ins1.classdef is None or r_ins2.classdef is None: basedef = None else: basedef = r_ins1.classdef.commonbase(r_ins2.classdef) if basedef == r_ins2.classdef: # r_ins1 is an instance of the subclass: converting to parent v = llops.genop('ooupcast', [v], resulttype=r_ins2.lowleveltype) return v elif basedef == r_ins1.classdef: # r_ins2 is an instance of the subclass: potentially unsafe # casting, but we do it anyway (e.g. the annotator produces # such casts after a successful isinstance() check) v = llops.genop('oodowncast', [v], resulttype=r_ins2.lowleveltype) return v else: return NotImplemented
class __extend__(pairtype(SomeList, SomeInteger)): def mul((lst1, int2)): bk = getbookkeeper() return lst1.listdef.offspring(bk) def getitem((lst1, int2)): position = getbookkeeper().position_key return lst1.listdef.read_item(position) getitem.can_only_throw = [] def getitem_idx((lst1, int2)): position = getbookkeeper().position_key return lst1.listdef.read_item(position) getitem_idx.can_only_throw = [IndexError] def setitem((lst1, int2), s_value): lst1.listdef.mutate() lst1.listdef.generalize(s_value)
class __extend__(pairtype(SomeFloat, SomeFloat)): def union((flt1, flt2)): if not TLS.allow_int_to_float: # in this mode, if one of the two is actually the # subclass SomeInteger, complain if isinstance(flt1, SomeInteger) or isinstance(flt2, SomeInteger): raise UnionError(flt1, flt2) return SomeFloat() add = sub = mul = union def div((flt1, flt2)): return SomeFloat() div.can_only_throw = [] truediv = div # repeat these in order to copy the 'can_only_throw' attribute inplace_div = div inplace_truediv = truediv
class __extend__(pairtype(SomeBool, SomeBool)): def union((boo1, boo2)): s = SomeBool() if getattr(boo1, 'const', -1) == getattr(boo2, 'const', -2): s.const = boo1.const if hasattr(boo1, 'knowntypedata') and \ hasattr(boo2, 'knowntypedata'): ktd = merge_knowntypedata(boo1.knowntypedata, boo2.knowntypedata) s.set_knowntypedata(ktd) return s def and_((boo1, boo2)): s = SomeBool() if boo1.is_constant(): if not boo1.const: s.const = False else: return boo2 if boo2.is_constant(): if not boo2.const: s.const = False return s def or_((boo1, boo2)): s = SomeBool() if boo1.is_constant(): if boo1.const: s.const = True else: return boo2 if boo2.is_constant(): if boo2.const: s.const = True return s def xor((boo1, boo2)): s = SomeBool() if boo1.is_constant() and boo2.is_constant(): s.const = boo1.const ^ boo2.const return s
class __extend__(pairtype(InteriorPtrRepr, IntegerRepr)): def rtype_getitem((r_ptr, r_item), hop): ARRAY = r_ptr.resulttype.TO ITEM_TYPE = ARRAY.OF if isinstance(ITEM_TYPE, lltype.ContainerType): v_array, v_index = hop.inputargs(r_ptr, lltype.Signed) INTERIOR_PTR_TYPE = r_ptr.lowleveltype._interior_ptr_type_with_index(ITEM_TYPE) cflags = hop.inputconst(lltype.Void, {'flavor': 'gc'}) args = [flowmodel.Constant(INTERIOR_PTR_TYPE, lltype.Void), cflags] v_interior_ptr = hop.genop('malloc', args, resulttype=lltype.Ptr(INTERIOR_PTR_TYPE)) hop.genop('setfield', [v_interior_ptr, flowmodel.Constant('ptr', lltype.Void), v_array]) hop.genop('setfield', [v_interior_ptr, flowmodel.Constant('index', lltype.Void), v_index]) return v_interior_ptr else: v_self, v_index = hop.inputargs(r_ptr, lltype.Signed) vlist = r_ptr.getinteriorfieldargs(hop, v_self) + [v_index] return hop.genop('getinteriorfield', vlist, resulttype=ITEM_TYPE)
class __extend__(pairtype(Repr, Repr)): def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) roriginal1 = robj1 roriginal2 = robj2 if robj1.lowleveltype is Void: robj1 = robj2 elif robj2.lowleveltype is Void: robj2 = robj1 if (not isinstance(robj1.lowleveltype, Ptr) or not isinstance(robj2.lowleveltype, Ptr)): raise TyperError('is of instances of the non-pointers: %r, %r' % (roriginal1, roriginal2)) if robj1.lowleveltype != robj2.lowleveltype: raise TyperError( 'is of instances of different pointer types: %r, %r' % (roriginal1, roriginal2)) v_list = hop.inputargs(robj1, robj2) return hop.genop('ptr_eq', v_list, resulttype=Bool)
def improve((ins1, ins2)): if ins1.classdef is None: resdef = ins2.classdef elif ins2.classdef is None: resdef = ins1.classdef else: basedef = ins1.classdef.commonbase(ins2.classdef) if basedef is ins1.classdef: resdef = ins2.classdef elif basedef is ins2.classdef: resdef = ins1.classdef else: if ins1.can_be_None and ins2.can_be_None: return s_None else: return s_ImpossibleValue res = SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) if ins1.contains(res) and ins2.contains(res): return res # fine else: # this case can occur in the presence of 'const' attributes, # which we should try to preserve. Fall-back... thistype = pairtype(SomeInstance, SomeInstance) return super(thistype, pair(ins1, ins2)).improve()
class __extend__(pairtype(TupleRepr, Repr)): def rtype_contains((r_tup, r_item), hop): s_tup = hop.args_s[0] if not s_tup.is_constant(): raise TyperError("contains() on non-const tuple") t = s_tup.const s_item = hop.args_s[1] r_item = hop.args_r[1] v_arg = hop.inputarg(r_item, arg=1) ll_eq = r_item.get_ll_eq_function() or _ll_equal v_result = None for x in t: s_const_item = hop.rtyper.annotator.bookkeeper.immutablevalue(x) if not s_item.contains(s_const_item): continue # corner case, see test_constant_tuple_contains_bug c_tuple_item = hop.inputconst(r_item, x) v_equal = hop.gendirectcall(ll_eq, v_arg, c_tuple_item) if v_result is None: v_result = v_equal else: v_result = hop.genop("int_or", [v_result, v_equal], resulttype=Bool) hop.exception_cannot_occur() return v_result or hop.inputconst(Bool, False)
# ____________________________________________________________ def make_missing_op(rcls, opname): attr = 'rtype_' + opname if not hasattr(rcls, attr): def missing_rtype_operation(self, hop): raise MissingRTypeOperation("unimplemented operation: " "'%s' on %r" % (opname, self)) setattr(rcls, attr, missing_rtype_operation) for opname in unaryop.UNARY_OPERATIONS: make_missing_op(Repr, opname) for opname in binaryop.BINARY_OPERATIONS: make_missing_op(pairtype(Repr, Repr), opname) # not in BINARY_OPERATIONS make_missing_op(pairtype(Repr, Repr), 'contains') class __extend__(pairtype(Repr, Repr)): def convert_from_to((r_from, r_to), v, llops): return NotImplemented # ____________________________________________________________ class VoidRepr(Repr): lowleveltype = Void def get_ll_eq_function(self): return None def get_ll_hash_function(self): return ll_hash_void get_ll_fasthash_function = get_ll_hash_function
'getitem_idx', 'getitem_key', 'getitem_idx_key', 'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv', 'inplace_floordiv', 'inplace_div', 'inplace_mod', 'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or', 'inplace_xor', 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp', 'coerce', ] +[opname+'_ovf' for opname in """add sub mul floordiv div mod lshift """.split() ]) for opname in BINARY_OPERATIONS: missing_operation(pairtype(SomeObject, SomeObject), opname) class __extend__(pairtype(SomeObject, SomeObject)): def union((obj1, obj2)): raise UnionError(obj1, obj2) # inplace_xxx ---> xxx by default def inplace_add((obj1, obj2)): return pair(obj1, obj2).add() def inplace_sub((obj1, obj2)): return pair(obj1, obj2).sub() def inplace_mul((obj1, obj2)): return pair(obj1, obj2).mul() def inplace_truediv((obj1, obj2)): return pair(obj1, obj2).truediv() def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv() def inplace_div((obj1, obj2)): return pair(obj1, obj2).div() def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod() def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift()
resulttype = r_ins2.lowleveltype) return v else: return NotImplemented def rtype_is_((r_ins1, r_ins2), hop): if r_ins1.gcflavor != r_ins2.gcflavor: # obscure logic, the is can be true only if both are None v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr()) return hop.gendirectcall(ll_both_none, v_ins1, v_ins2) if r_ins1.classdef is None or r_ins2.classdef is None: basedef = None else: basedef = r_ins1.classdef.commonbase(r_ins2.classdef) r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor) return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop) rtype_eq = rtype_is_ def rtype_ne(rpair, hop): v = rpair.rtype_eq(hop) return hop.genop("bool_not", [v], resulttype=Bool) # ____________________________________________________________ # # Low-level implementation of operations on classes and instances # doesn't work for non-gc stuff! def ll_cast_to_object(obj): return cast_pointer(OBJECTPTR, obj)