[IronPython] tuple subclass and super()

Dino Viehland dinov at exchange.microsoft.com
Wed Sep 27 20:04:17 CEST 2006

This is a bug, thanks for the report.  I've opened CodePlex bug #3758 to track this (http://www.codeplex.com/WorkItem/View.aspx?ProjectName=IronPython&WorkItemId=3758).

I'm going to push to try and get this fixed in v1.0.1 but it might not quite make it (which means it might need to wait until 1.0.2 or 1.1). The rest of this is the technical details that can safely be ignored if you don't care about them :).

The issue here is that in order to call super methods we need to create a helper method that does the dispatch to the base method.  We need to do this because calls to base method from outside a type are non-verifiable.  When we do this we back-patch the original type's dictionary with a new method that takes the derived type.  We end up generating a type like:

class IronPython.Runtime.NewTypes.Tuple_1 : IronPython.Runtime.Tuple {
        public void base#Equals(object other) {
                return base.Equals(other);

And Tuple gets updated to include base#Equals(Tuple_1 self, object other) in addition to base#Equals(Tuple self, obhect other) (then the method binder takes over and does the right thing at call time w/ the self parameter).

The problem here is that we're only back-patching for the name Equals, and not both Equals and __eq__.

I believe the fix is to replace this if block in IronPython.Compiler.Generation.NewTypeMaker with this one:

                if (methodName.StartsWith("#base#")) {                          // <-- already there
                    ParameterInfo[] pis= mi.GetParameters();
                    Type[] types = new Type[pis.Length];
                    int i = 0;
                    foreach (ParameterInfo pi in pis) {
                        types[i++] = pi.ParameterType;
                    MethodInfo overriding = this.baseType.GetMethod(methodName.Substring(6),
                        BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
                    Debug.Assert(overriding != null);

                    string newName = GetBaseName(mi, specialNames);                     // <-- also already there
                    string outName;
                    NameType nt = NameConverter.TryGetName(Ops.GetDynamicTypeFromType(baseType) as ReflectedType, overriding, out outName);
                    if (nt != NameType.None && outName != newName) {
                        rt.StoreReflectedBaseMethod(outName, mi, nt);

                    rt.StoreReflectedBaseMethod(newName, mi, NameType.Method);   // <-- also already there
                } // <-- also already there

Everything else is new code.  I'm still running tests against this but I think this is the correct fix.

-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of hardcoded.software at gmail.com
Sent: Wednesday, September 27, 2006 6:43 AM
To: users at lists.ironpython.com
Subject: [IronPython] tuple subclass and super()


I am evaluating whether it is possible for me to jump into the IronPython bandwagon by running my test units through ipy, but I have a big problem with one of my classes, which is a subclass of tuple. I will not post my whole class here, but a re-creation of the problem:

class Foobar(tuple):
    def __new__(cls,value):
        if isinstance(value,Foobar):
            return value
        return tuple.__new__(cls,value)

    def __eq__(self,other):
        other = Foobar(other)
        return super(Foobar,self).__eq__(other)

foobar = Foobar('foo')
print foobar == 'foo'

(It might look silly, but it is actually useful for me to do that.) Under CPython, it works (True is printed), but with IPY, I get an access violation (caused by a stack overflow I think).

users mailing list
users at lists.ironpython.com

More information about the Ironpython-users mailing list