def attach_class_attr_accessor(self, mangled, oovalue): def ll_getclassattr(self): return oovalue M = ootype.Meth([], ootype.typeOf(oovalue)) ll_getclassattr = func_with_new_name(ll_getclassattr, 'll_get_' + mangled) graph = self.rtyper.annotate_helper(ll_getclassattr, [self.lowleveltype]) m = ootype.meth(M, _name=mangled, _callable=ll_getclassattr, graph=graph) ootype.addMethods(self.lowleveltype, {mangled: m})
def test_checkvirtual_simple(): A = Instance("A", ROOT) B = Instance("B", A) addMethods(A, {"foo": meth(Meth([], Void)), "bar": meth(Meth([], Void))}) addMethods(B, {"foo": meth(Meth([], Void))}) check_virtual_methods() assert A._methods["foo"]._virtual == True assert A._methods["bar"]._virtual == False assert B._methods["foo"]._virtual == False
def test_checkvirtual_brother(): A = Instance("A", ROOT) B1 = Instance("B1", A) B2 = Instance("B2", A) addMethods(A, {"foo": meth(Meth([], Void)), "bar": meth(Meth([], Void))}) addMethods(B1, {"foo": meth(Meth([], Void))}) check_virtual_methods() assert A._methods["foo"]._virtual == True assert A._methods["bar"]._virtual == False assert B1._methods["foo"]._virtual == False assert "foo" not in B2._methods
def test_checkvirtual_deep(): A = Instance("A", ROOT) B = Instance("B", A) C = Instance("C", B) addMethods(A, {"foo": meth(Meth([], Void)), "bar": meth(Meth([], Void))}) addMethods(C, {"foo": meth(Meth([], Void))}) check_virtual_methods() assert A._methods["foo"]._virtual == True assert A._methods["bar"]._virtual == False assert "foo" not in B._methods assert C._methods["foo"]._virtual == False
def attach_abstract_class_attr_accessor(self, mangled, attrtype): M = ootype.Meth([], attrtype) m = ootype.meth(M, _name=mangled, abstract=True) ootype.addMethods(self.lowleveltype, {mangled: m})
def _setup_repr_final(self): if self.classdef is None: return AbstractInstanceRepr._setup_repr_final(self) # we attach methods here and not in _setup(), because we want # to be sure that all the reprs of the input arguments of all # our methods have been computed at this point methods = {} selfattrs = self.classdef.attrs for mangled, (name, s_value) in self.allmethods.iteritems(): methdescs = s_value.descriptions origin = dict([(methdesc.originclassdef, methdesc) for methdesc in methdescs]) if self.classdef in origin: methdesc = origin[self.classdef] else: if name in selfattrs: for superdef in self.classdef.getmro(): if superdef in origin: # put in methods methdesc = origin[superdef] break else: # abstract method methdesc = None else: continue # get method implementation from rpython.rtyper.ootypesystem.rpbc import MethodImplementations methimpls = MethodImplementations.get(self.rtyper, s_value) m_impls = methimpls.get_impl(mangled, methdesc, is_finalizer=name == "__del__") methods.update(m_impls) ootype.addMethods(self.lowleveltype, methods) # step 3: provide accessor methods for class attributes that # are really overridden in subclasses. Must be done here # instead of _setup_repr to avoid recursion problems if class # attributes are Instances of self.lowleveltype. for mangled, (s_value, value) in self.classattributes.items(): r = self.rtyper.getrepr(s_value) if value is None: self.attach_abstract_class_attr_accessor( mangled, r.lowleveltype) else: oovalue = r.convert_desc_or_const(value) self.attach_class_attr_accessor(mangled, oovalue) # step 4: do the same with instance fields whose default # values are overridden in subclasses. Not sure it's the best # way to do it. overridden_defaults = {} if self.classdef is not None: for name, constant in self.classdef.classdesc.classdict.iteritems( ): # look for the attrdef in the superclasses classdef = self.classdef.basedef attrdef = None while classdef is not None: if name in classdef.attrs: attrdef = classdef.attrs[name] break classdef = classdef.basedef if attrdef is not None and not attrdef.readonly: # it means that the default value for this field # is overridden in this subclass. Record we know # about it repr = self.rtyper.getrepr(attrdef.s_value) oot = repr.lowleveltype mangled = mangle(name, self.rtyper.getconfig()) value = self.classdef.classdesc.read_attribute(name) default = repr.convert_desc_or_const(value) overridden_defaults[mangled] = oot, default ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults)
def _setup_repr_final(self): if self.classdef is None: return AbstractInstanceRepr._setup_repr_final(self) # we attach methods here and not in _setup(), because we want # to be sure that all the reprs of the input arguments of all # our methods have been computed at this point methods = {} selfattrs = self.classdef.attrs for mangled, (name, s_value) in self.allmethods.iteritems(): methdescs = s_value.descriptions origin = dict([(methdesc.originclassdef, methdesc) for methdesc in methdescs]) if self.classdef in origin: methdesc = origin[self.classdef] else: if name in selfattrs: for superdef in self.classdef.getmro(): if superdef in origin: # put in methods methdesc = origin[superdef] break else: # abstract method methdesc = None else: continue # get method implementation from rpython.rtyper.ootypesystem.rpbc import MethodImplementations methimpls = MethodImplementations.get(self.rtyper, s_value) m_impls = methimpls.get_impl(mangled, methdesc, is_finalizer=name == "__del__") methods.update(m_impls) ootype.addMethods(self.lowleveltype, methods) # step 3: provide accessor methods for class attributes that # are really overridden in subclasses. Must be done here # instead of _setup_repr to avoid recursion problems if class # attributes are Instances of self.lowleveltype. for mangled, (s_value, value) in self.classattributes.items(): r = self.rtyper.getrepr(s_value) if value is None: self.attach_abstract_class_attr_accessor(mangled, r.lowleveltype) else: oovalue = r.convert_desc_or_const(value) self.attach_class_attr_accessor(mangled, oovalue) # step 4: do the same with instance fields whose default # values are overridden in subclasses. Not sure it's the best # way to do it. overridden_defaults = {} if self.classdef is not None: for name, constant in self.classdef.classdesc.classdict.iteritems(): # look for the attrdef in the superclasses classdef = self.classdef.basedef attrdef = None while classdef is not None: if name in classdef.attrs: attrdef = classdef.attrs[name] break classdef = classdef.basedef if attrdef is not None and not attrdef.readonly: # it means that the default value for this field # is overridden in this subclass. Record we know # about it repr = self.rtyper.getrepr(attrdef.s_value) oot = repr.lowleveltype mangled = mangle(name, self.rtyper.getconfig()) value = self.classdef.classdesc.read_attribute(name) default = repr.convert_desc_or_const(value) overridden_defaults[mangled] = oot, default ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults)
def test_nonvirtual(): A = Instance("A", ROOT) addMethods(A, {"foo": meth(Meth([], Void))}) check_virtual_methods() assert A._methods["foo"]._virtual == False