From: <pj...@us...> - 2009-10-26 04:16:55
|
Revision: 6902 http://jython.svn.sourceforge.net/jython/?rev=6902&view=rev Author: pjenvey Date: 2009-10-26 04:16:36 +0000 (Mon, 26 Oct 2009) Log Message: ----------- fix handling of the corner case where the winning metatype differs from the specified type. we were calling the wrong __new__, and its __init__ twice Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-10-25 18:31:36 UTC (rev 6901) +++ trunk/jython/Lib/test/test_class_jy.py 2009-10-26 04:16:36 UTC (rev 6902) @@ -190,7 +190,23 @@ raise IndexError, "Fraid not" self.assertRaises(IndexError, A().__getitem__, 'b') + def test_winning_metatype(self): + class Meta(type): + def __new__(cls, name, bases, attrs): + attrs['spam'] = name + attrs['counter'] = 0 + return type.__new__(cls, name, bases, attrs) + def __init__(cls, name, bases, attrs): + cls.counter += 1 + class Base(object): + __metaclass__ = Meta + Foo = type('Foo', (Base,), {}) + # Previously we called the wrong __new__ + self.assertEqual(Foo.spam, 'Foo') + # and called __init__ twice + self.assertEqual(Foo.counter, 1) + class ClassNamelessModuleTestCase(unittest.TestCase): def setUp(self): Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-10-25 18:31:36 UTC (rev 6901) +++ trunk/jython/src/org/python/core/PyType.java 2009-10-26 04:16:36 UTC (rev 6902) @@ -144,11 +144,10 @@ PyType winner = findMostDerivedMetatype(tmpBases, metatype); if (winner != metatype) { - PyObject winner_new_ = winner.lookup("__new__"); - if (winner_new_ != null && winner_new_ != new_) { - return invoke_new_(new_, winner, false, - new PyObject[] {new PyString(name), bases, dict}, - Py.NoKeywords); + PyObject winnerNew = winner.lookup("__new__"); + if (winnerNew != null && winnerNew != new_) { + return invokeNew(winnerNew, winner, false, + new PyObject[] {new PyString(name), bases, dict}, Py.NoKeywords); } metatype = winner; } @@ -438,24 +437,19 @@ } } - private static PyObject invoke_new_(PyObject new_, PyType type, boolean init, PyObject[] args, - String[] keywords) { - PyObject newobj; + private static PyObject invokeNew(PyObject new_, PyType type, boolean init, PyObject[] args, + String[] keywords) { + PyObject obj; if (new_ instanceof PyNewWrapper) { - newobj = ((PyNewWrapper)new_).new_impl(init, type, args, keywords); + obj = ((PyNewWrapper)new_).new_impl(init, type, args, keywords); } else { int n = args.length; - PyObject[] type_prepended = new PyObject[n + 1]; - System.arraycopy(args, 0, type_prepended, 1, n); - type_prepended[0] = type; - newobj = new_.__get__(null, type).__call__(type_prepended, keywords); + PyObject[] typePrepended = new PyObject[n + 1]; + System.arraycopy(args, 0, typePrepended, 1, n); + typePrepended[0] = type; + obj = new_.__get__(null, type).__call__(typePrepended, keywords); } - // special case type(x) - if (type == TYPE && args.length == 1 && keywords.length == 0) { - return newobj; - } - newobj.dispatch__init__(type, args, keywords); - return newobj; + return obj; } /** @@ -1479,9 +1473,16 @@ final PyObject type___call__(PyObject[] args, String[] keywords) { PyObject new_ = lookup("__new__"); if (!instantiable || new_ == null) { - throw Py.TypeError("cannot create '" + name + "' instances"); + throw Py.TypeError(String.format("cannot create '%.100s' instances", name)); } - return invoke_new_(new_, this, true, args, keywords); + + PyObject obj = invokeNew(new_, this, true, args, keywords); + // special case type(x) + if (this == TYPE && args.length == 1 && keywords.length == 0) { + return obj; + } + obj.dispatch__init__(this, args, keywords); + return obj; } protected void __rawdir__(PyDictionary accum) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |