def create_ext_command_attrs(): regen_const_info = clr.GetClrType(RegenerationAttribute).GetConstructor(Array[Type]((RegenerationOption,))) regen_attr_builder = CustomAttributeBuilder(regen_const_info, Array[object]((RegenerationOption.Manual,))) # add TransactionAttribute to type trans_constructor_info = clr.GetClrType(TransactionAttribute).GetConstructor(Array[Type]((TransactionMode,))) trans_attrib_builder = CustomAttributeBuilder(trans_constructor_info, Array[object]((TransactionMode.Manual,))) return [regen_attr_builder, trans_attrib_builder]
def emit_classattribs(self, typebld): if hasattr(self, '_clrclassattribs'): for attrib_info in self._clrclassattribs: if isinstance(attrib_info, type): ci = clr.GetClrType(attrib_info).GetConstructor(()) cab = CustomAttributeBuilder(ci, ()) elif isinstance(attrib_info, CustomAttributeDecorator): cab = attrib_info.GetBuilder() else: make_decorator = attrib_info() cab = make_decorator.GetBuilder() typebld.SetCustomAttribute(cab)
def make_cab(attrib_type, *args, **kwds): clrtype = clr.GetClrType(attrib_type) argtypes = tuple(map(lambda x:clr.GetClrType(type(x)), args)) ci = clrtype.GetConstructor(argtypes) props = ([],[]) fields = ([],[]) for kwd in kwds: pi = clrtype.GetProperty(kwd) if pi is not None: props[0].append(pi) props[1].append(kwds[kwd]) else: fi = clrtype.GetField(kwd) if fi is not None: fields[0].append(fi) fields[1].append(kwds[kwd]) else: raise TypeError("No %s Member found on %s" % (kwd, clrtype.Name)) return CustomAttributeBuilder(ci, args, tuple(props[0]), tuple(props[1]), tuple(fields[0]), tuple(fields[1]))
def test_critical_custom_attributes(): ''' Ensure adding custom attributes to a Python class remains supported. ''' global called global TYPE_COUNTER TYPE_COUNTER += 1 import clr from System.Reflection.Emit import CustomAttributeBuilder, OpCodes clr.AddReference("Microsoft.Scripting") from Microsoft.Scripting.Generation import Snippets clr.AddReference("System.Xml") from System.Xml.Serialization import XmlRootAttribute xmlroot_clrtype = clr.GetClrType(XmlRootAttribute) xmlroot_ci = xmlroot_clrtype.GetConstructor((clr.GetClrType(str), )) XmlRootInstance = CustomAttributeBuilder( xmlroot_ci, ("product", ), (xmlroot_clrtype.GetProperty("Namespace"), ), ("http://ironpython.codeplex.com", ), (), ()) called = False class MyType(type): def __clrtype__(self): global called baseType = super(MyType, self).__clrtype__() typegen = Snippets.Shared.DefineType( "faux type" + str(TYPE_COUNTER), baseType, True, False) typebld = typegen.TypeBuilder for ctor in baseType.GetConstructors(): ctorparams = ctor.GetParameters() ctorbld = typebld.DefineConstructor( ctor.Attributes, ctor.CallingConvention, tuple([p.ParameterType for p in ctorparams])) ilgen = ctorbld.GetILGenerator() ilgen.Emit(OpCodes.Ldarg, 0) for index in range(len(ctorparams)): ilgen.Emit(OpCodes.Ldarg, index + 1) ilgen.Emit(OpCodes.Call, ctor) ilgen.Emit(OpCodes.Ret) typebld.SetCustomAttribute(XmlRootInstance) called = True return typebld.CreateType() class X(object): __metaclass__ = MyType #Verification AreEqual(called, True) x = X() x_clrtype = clr.GetClrType(X) AreEqual( x_clrtype.GetCustomAttributes(XmlRootAttribute, True)[0].ElementName, "product") AreEqual( x_clrtype.GetCustomAttributes(XmlRootAttribute, True)[0].Namespace, "http://ironpython.codeplex.com")