[Ironpython-users] Set __metaclass__ on .NET type?

Dino Viehland dinov at microsoft.com
Thu Jun 21 07:53:16 CEST 2012

It's not really exposed, but it is "possible" - we do it for ctypes.

For ctypes we use an internal call such as PythonType.SetPythonType(typeof(Suite), new SuiteMetaType());
where SuiteMetaType is a subclass of PythonType.  If this was a public API you'd do
that in a static initializer of Suite so it happens before any Suite's are made.

But SetPythonType isn't public...  I could see making it public not being too big
of a deal - we are all consenting adults and there is a pretty safe way to use
it.  I'd suggest extending PythonTypeAttribute so the meta-class can be specified
but that wouldn't allow a whole lot of flexibility in instantiating the meta-class.

I think my biggest concern about this is that these meta-classes bleed across
runtime instances so you need to be careful about what you do with them, but
I'm guessing that wouldn't be an issue for most people.  

Another way to accomplish this if you're exposing it via a built-in module would
be to publish a hand-created subtype via the PerformModuleReload method 
doing something like:

dict["Suite"] = PythonType.__new__(<code context>, 
    new PythonTuple(new object[] { typeof(Suite) }),
    {"__metaclass__": new YourSubClassOfPythonType() },

That'd create a new sub-type of your Suite class which has its meta-class
set to your meta-class.  The user can then subclass this class rather than
subclassing your .NET class directly.  It's an extra level of indirection, but
it also generally gets the per-runtime isolation right.

In general I don't think what you're trying to do is too crazy, at least a more
elegant solution doesn't really spring to my mind.  

> -----Original Message-----
> From: ironpython-users-bounces+dinov=microsoft.com at python.org
> [mailto:ironpython-users-bounces+dinov=microsoft.com at python.org] On
> Behalf Of Slide
> Sent: Wednesday, June 20, 2012 10:22 PM
> To: ironpython-users at python.org
> Subject: [Ironpython-users] Set __metaclass__ on .NET type?
> I am playing around with using IronPython to replace a custom language we
> use to define tasks and suites of tasks for an in-house automated testing
> framework. Currently we have something like
> task FooTask {
>     cmdline = "...";
>     file somefile.txt = (.
> This will have some content, and even supports variables: $VAR1
>     .)
> }
> table SomeTable = {
>     VAR1
>     1
>     2
>     3
> }
> suite SomeSuite {
>     FooTask(SomeTable);
> }
> This would permute FooTask with VAR1 for each row in the table.
> This is a bit more information than you probably need, but it will give you
> the feel for what I am trying to do.
> I was thinking I could reuse the objects that I now create in the parser of
> the custom language as base types for Python object
> class FooTask(Task):
>     def __init__(self, variables):
>         self.SetCmdLine("....")
>         self.Files.Add("somefile.txt", "This will have some content, and even
> supports variables: $VAR1")
> class SomeSuite(Suite):
>     def __init__(self):
>         self.AddItem(FooTask() * [ { "VAR1" : "1" }, {"VAR1" : "2" }, { "VAR1" : "3"
> } ])
> I can easily implement __mult__ and other such operations to handle the
> permutation and other operations I currently support.
> Now, what I _think_ I need metaclasses for is that when FooTask or
> SomeSuite is created, I need to be able to add the instance to my symbol
> table so I can then create the output that I need to.
> Am I thinking incorrectly about the need for metaclasses? I would like to
> keep as much of the details as possible away from the users, so I was
> thinking if I could hook into the object creation, I could add the instance to
> my symbol table in the metaclass. For this, I would need to set
> __metaclass__ on the base classes (Task and Suite), which are .NET objects,
> is this doable?
> Am I trying to fit a square peg into a round hole in general?
> Thanks for reading my ramblings :-)
> slide
> --
> Website: http://earl-of-code.com
> _______________________________________________
> Ironpython-users mailing list
> Ironpython-users at python.org
> http://mail.python.org/mailman/listinfo/ironpython-users

More information about the Ironpython-users mailing list