[IronPython] Using Python special methods in C#

Dino Viehland dinov at exchange.microsoft.com
Mon Jul 28 18:05:45 CEST 2008


Oh, yeah, I guess I was wrong about call/get/set/delete member customizers...  Those are handled by the default DLR binder and Python doesn't recognize the __*__ names.  I failed to consider that - sorry about that :)  It's certainly true for all the complex Python operators such as binary operators, unary operators, indexing, slicing, etc...

Instead for these you can use methods w/ special names which provide that functionality.  That includes:

GetCustomMember(string name) - gets a 1st try at all attribute access (e.g. __getattribute__)
GetBoundMember(string name) - gets a last try at attribute access (e.g. __getattr__)
SetMember(string name, object value) - gets 1st try at all attribute sets (e.g. __setattr__)
SetMemberAfter(string name, object value) - gets the last try at attribute sets (no Python equivalent, runs if no .NET binding is available)
DeleteMember(string name) - runs for deletes (__delattr__, there are no .NET deletes so no before/after semantics)

These methods can have a strongly typed return type if you know you'll always return the same value.  They can also return OperationFailed.Value to indicate that normal processing should continue.  In other words you could have a GetCustomMember & GetBoundMember and GCM could defer back by returning OperationFailed.Value.  All the methods need to be marked with a [SpecialName] attribute.

Likewise you can define a Call method:

[SpecialName]
object Call(string someArg, int someOtherArg)

and you can have various strongly typed overloads, etc...


-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Michael Foord
Sent: Saturday, July 26, 2008 1:33 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Using Python special methods in C#

Hello Dino,

The original question was about '__call__'. As far as I can *tell* that
doesn't work either:

namespace example
{
    public class Example
    {
        public int __call__(string key)
        {
            Console.WriteLine(key);
            return 3;
        }

    }
}


 >>> clr.AddReference('example')
 >>> from example import Example
 >>>
 >>> e = Example()
 >>> e('r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Example is not callable
 >>> e.__call__('r')
r
3
 >>>

Michael

Dino Viehland wrote:
> Srivatsn's blog is an important piece of the puzzle, but the more general answer is implementing the __*__ method directly should always work.  If it doesn't then it's a bug - like where __repr__ wasn't working w/o implementing the interface until recently.
>
> But there is a good reason to not implement the __*__ method - and that's ensuring that your objects will work good in a multi-language environment.  What IronPython does to expose .NET objects into Python is it maps a large number of .NET interfaces and methods into Python methods.  If you'd like to see the all of the mappings they're contained entirely in TypeInfo.cs.  So instead of implementing __getitem__ you can implement a C# indexer,  instead of __enter__/__exit__ you can implement IDisposable - assuming you're not doing more interesting things w/ __enter__/__exit__, etc...  If there's some mapping that you think should exist but we don't have let us know - for example until recently we had overlooked mapping IDisposable.
>
> To get the best interop if there's a .NET interface or operator method that maps onto the Python methods you should use that.  That includes the extended operators that we've defined for the DLR default binder like GetCustomMember as Srivatsn's blog demonstrates.  Otherwise fallback to the __*_- method.
>
> -----Original Message-----
> From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Michael Foord
> Sent: Sunday, July 13, 2008 10:21 AM
> To: Discussion of IronPython
> Subject: Re: [IronPython] Using Python special methods in C#
>
> Dan Eloff wrote:
>
>> Something I've found a little difficult in C# is python special
>> methods. It seems sometimes you can just declare them on the C# class,
>> (__repr__?) and they will work, other times you need to implement an
>> interface (__call__?) is there any place this is documented?
>>
>> I'm a little confused about how to add special methods on C# classes.
>>
>> I want to add __getattr__ to a C# class (actually a subclass of
>> PythonDictionary), and I have no idea how.
>>
>>
>
> This example from Srivatsn shows you how:
>
> http://blogs.msdn.com/srivatsn/archive/2008/04/12/turning-your-net-object-models-dynamic-for-ironpython.aspx
>
> Michael
>
>> Thanks,
>> -Dan
>> _______________________________________________
>> Users mailing list
>> Users at lists.ironpython.com
>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>
>>
>
>
> --
> http://www.ironpythoninaction.com/
> http://www.voidspace.org.uk/
> http://www.trypython.org/
> http://www.ironpython.info/
> http://www.theotherdelia.co.uk/
> http://www.resolverhacks.net/
>
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>


--
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/
http://www.trypython.org/
http://www.ironpython.info/
http://www.theotherdelia.co.uk/
http://www.resolverhacks.net/

_______________________________________________
Users mailing list
Users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list