Message7543

Author jeff.allen
Recipients fwierzbicki, jeff.allen, pjenvey
Date 2012-12-05.07:53:00
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1354693981.58.0.525604838263.issue1996@psf.upfronthosting.co.za>
In-reply-to
Content
I've run across what may be a bug in the core treatment of multiple 
inheritance when the slots array is active in a base.

Indications are that the slots array of only the first base mentioned  
is honoured. I came across this in work on the IO library where the 
exception class is defined (in CPython _pyio and _io):

class UnsupportedOperation(ValueError, IOError):
     pass

Now this class (both the one defined in Python and my Java equivalent 
using Py.makeClass()) causes a java.lang.ArrayIndexOutOfBounds exception as soon as an instance is required. This happens at the point where "errno" is assigned to slots[0] (by the __init__() of EnvironmentError, ancestor of IOError). The type that results in either case has zero slots, and that's where the out-of-bounds error arises.

This JUnit test fails quite nicely too:
     @Test
     public void pythonMyExc2() {
         interp.exec("class MyExc2(ValueError, IOError):\n    pass\n\n");
         try {
             interp.exec("raise MyExc2()");
             fail("MyExc2 not raised when expected");
         } catch (PyException e) {
             assertEquals("<class '__main__.MyExc2'>", e.type.toString());
         }
     }

Put the bases in the other order, and it works: the type you get has 3 
slots. (There's my work-around.)

I've tracked the problematic logic down to PyType.createAllSlots(), 
called from PyType newType(), which only takes notice of the number of 
slots in the first base mentioned (which becomes type.base) rather than 
making some aggregation involving all the bases. This is probably a bug.


*** Philip Jenvey adds (via the jython-dev list):

This is a nasty because:
a) the spec of how slots are handled, especially with inheritance, is pretty obscure. You can maybe get some idea from our test_slots_jy.py
b) the fact that our base exceptions define __slots__ is kind of a hack to simulate CPython's base exception attributes (that are stored as slot-like 'structure members' instead of in the __dict__).

... 

It *seems* like a bug in the slots handling. It'd be nice to reproduce this case without the exceptions as it would prove that (and would be a nice test for test_slots_jy.py). Otherwise maybe it's some strange interaction with how we're defining these exception slots.
History
Date User Action Args
2012-12-05 07:53:01jeff.allensetrecipients: + jeff.allen, fwierzbicki, pjenvey
2012-12-05 07:53:01jeff.allensetmessageid: <1354693981.58.0.525604838263.issue1996@psf.upfronthosting.co.za>
2012-12-05 07:53:01jeff.allenlinkissue1996 messages
2012-12-05 07:53:00jeff.allencreate