[IronPython] .NET constructors

Dino Viehland dinov at exchange.microsoft.com
Mon Jun 19 20:51:23 CEST 2006


This appears to be fixed for beta 8 - we've made a lot of changes to get to our final method dispatch story.  One of those changes involved getting rid of creating some optimized methods that wouldn't have worked for more than 5 args.  Likely this fixed the issue.

That doesn't solve all your issues though - to override a normal CLR type's ctor you'll need to override __new__ instead of __init__.

>>> class PyTest(Test):
...   def __new__(cls, a):
...     print 'XXX'
...     return Test.__new__(cls, a, 2)


And overriding new also makes the kw-arg case work as well.

Why __new__ instead of __init__?  In Python __init__ can be called explicitly on any instance after it has been created.  You can't do this w/ C# classes & their ctors, so the mapping to __new__ is much more appropriate.

We're planning on releasing Beta 8 later today, but you can get the current sources that include these fixes at http://www.codeplex.com/SourceControl/ListDownloadableCommits.aspx?ProjectName=IronPython



-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Jonathan Jacobs
Sent: Monday, June 19, 2006 2:08 AM
To: IronPython List
Subject: [IronPython] .NET constructors

Hi,

(I didn't see any of these things on the CodePlex issue tracker, sorry if these are old news.)

Trying to define a class that derives from my .NET object, with a single constructor that takes more than 4 arguments, explodes:

Test.cs:
public class Test {
     public Test(int a, int b, int c, int d, int e) {
     }
}

 >>> class PyTest(Test): pass
...
Traceback (most recent call last):
   File , line 0, in <stdin>##22
SystemError: too many args

Adding a second constructor that takes fewer than 5 arguments lets me at least define my class, however I get some odd behaviour from the 5-argument constructor (the 2-arg constructor works fine):

Test.cs:
public class Test {
     public Test(int a, int b) {
     }
     public Test(int a, int b, int c, int d, int e) {
     }
}

 >>> class PyTest(Test): pass
...
 >>> PyTest(1, 2)
<PyTest object at 0x000000000000002C>
 >>> PyTest(1, 2, 3, 4, 5)
Traceback (most recent call last):
   File , line 0, in <stdin>##35
TypeError: PyTest() takes at most 6 arguments (6 given)

Adding an initialiser to my derived class doesn't behave properly:

 >>> class PyTest(Test):
...   def __init__(self, a):
...     print 'XXX'
...     Test.__init__(self, a, 2)
...
 >>> PyTest(1) # try __init__
Traceback (most recent call last):
   File , line 0, in <stdin>##51
TypeError: PyTest() takes at least 3 arguments (2 given)  >>> PyTest(1, 2) # see if base object's constructor still exists then Traceback (most recent call last):
   File , line 0, in <stdin>##52
TypeError: __init__() takes exactly 2 arguments (3 given)

And finally, adding a kwarg gets us some more quirky behaviour:

 >>> class PyTest(Test):
...   def __init__(self, a, b=2):
...     print 'XXX'
...     Test.__init__(self, a, b)
...
 >>> PyTest(1)
Traceback (most recent call last):
   File , line 0, in <stdin>##67
TypeError: PyTest() takes at least 3 arguments (2 given)  >>> PyTest(1, 2) XXX <PyTest object at 0x0000000000000031>

Regards
--
Jonathan

When you meet a master swordsman,
show him your sword.
When you meet a man who is not a poet,
do not show him your poem.
                 -- Rinzai, ninth century Zen master _______________________________________________
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