Created
July 25, 2014 13:43
-
-
Save delicb/bb367688f62a412b39f9 to your computer and use it in GitHub Desktop.
IronPython CLR __clrtype__ manipultaion example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# from http://devhawk.net/2009/04/21/__clrtype__-metaclasses-ironpython-classes-under-the-hood/ | |
import clr | |
clr.AddReference('Microsoft.Scripting.dll') | |
clr.AddReference('Microsoft.Dynamic.dll') | |
clr.AddReference('IronPython.dll') | |
from Microsoft.Scripting.Generation import Snippets | |
from System.Reflection.Emit import OpCodes | |
from System.Reflection import FieldAttributes | |
from IronPython.Runtime.Types import ReflectedField | |
class ClrTypeMetaclass(type): | |
def __clrtype__(cls): | |
baseType = super(ClrTypeMetaclass, cls).__clrtype__() | |
typename = cls._clrnamespace + "." + cls.__name__ if hasattr(cls, '_clrnamespace') else cls.__name__ | |
typegen = Snippets.Shared.DefineType(typename, 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) | |
if hasattr(cls, "_clrfields"): | |
for fldname in cls._clrfields: | |
typebld.DefineField(fldname, clr.GetClrType(cls._clrfields[fldname]), FieldAttributes.Public) | |
new_type = typebld.CreateType() | |
if hasattr(cls, "_clrfields"): | |
for fldname in cls._clrfields: | |
fldinfo = new_type.GetField(fldname) | |
setattr(cls, fldname, ReflectedField(fldinfo)) | |
return new_type | |
class Product(object): | |
__metaclass__ = ClrTypeMetaclass | |
_clrnamespace = "DevHawk.IronPython.ClrTypeSeries" | |
_clrfields = { | |
'name': str, | |
'cost': float, | |
'quantity': int, | |
} | |
def __init__(self, name, cost, quantity): | |
self.name = name | |
self.cost = cost | |
self.quantity = quantity | |
def calc_total(self): | |
return self.cost * self.quantity | |
p = Product('Crunchy Frog', 5.99, 10) | |
t = p.GetType() | |
print(p.name) | |
namefi = t.GetField('name') | |
print(namefi.GetValue(p)) | |
namefi.SetValue(p, 'Spring Supprise') | |
print(p.name) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment