[Python-checkins] r85016 - in python/branches/release27-maint: Lib/test/test_class.py Lib/test/test_long.py Misc/NEWS Objects/abstract.c

mark.dickinson python-checkins at python.org
Sun Sep 26 12:37:12 CEST 2010


Author: mark.dickinson
Date: Sun Sep 26 12:37:12 2010
New Revision: 85016
Log:
Issue #9869: Make long() and PyNumber_Long return something of type
long for a class whose __long__ method returns a plain int. This
fixes an interpreter crash (due to long_subtype_new assuming
PyNumber_Long returns a long) when initializing an instance of a long
subclass from an object whose __long__ method returns a plain int.
Modified:
 python/branches/release27-maint/Lib/test/test_class.py
 python/branches/release27-maint/Lib/test/test_long.py
 python/branches/release27-maint/Misc/NEWS
 python/branches/release27-maint/Objects/abstract.c
Modified: python/branches/release27-maint/Lib/test/test_class.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_class.py	(original)
+++ python/branches/release27-maint/Lib/test/test_class.py	Sun Sep 26 12:37:12 2010
@@ -513,7 +513,7 @@
 
 callLst[:] = []
 as_long = long(mixIntAndLong)
- self.assertEquals(type(as_long), int)
+ self.assertEquals(type(as_long), long)
 self.assertEquals(as_long, 64)
 self.assertCallStack([('__long__', (mixIntAndLong,))])
 
Modified: python/branches/release27-maint/Lib/test/test_long.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_long.py	(original)
+++ python/branches/release27-maint/Lib/test/test_long.py	Sun Sep 26 12:37:12 2010
@@ -601,6 +601,22 @@
 slicemin, slicemax = X()[-2L**100:2L**100]
 self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
 
+ def test_issue9869(self):
+ # Issue 9869: Interpreter crash when initializing an instance
+ # of a long subclass from an object whose __long__ method returns
+ # a plain int.
+ class BadLong(object):
+ def __long__(self):
+ return 1000000
+
+ class MyLong(long):
+ pass
+
+ x = MyLong(BadLong())
+ self.assertIsInstance(x, long)
+ self.assertEqual(x, 1000000)
+
+
 # ----------------------------------- tests of auto int->long conversion
 
 def test_auto_overflow(self):
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sun Sep 26 12:37:12 2010
@@ -12,6 +12,11 @@
 Core and Builtins
 -----------------
 
+- Issue #9869: Make long() and PyNumber_Long return something of type
+ long for a class whose __long__ method returns a plain int. This
+ fixes an interpreter crash when initializing an instance of a long
+ subclass from an object whose __long__ method returns a plain int.
+
 - Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
 thread-local storage key.
 
Modified: python/branches/release27-maint/Objects/abstract.c
==============================================================================
--- python/branches/release27-maint/Objects/abstract.c	(original)
+++ python/branches/release27-maint/Objects/abstract.c	Sun Sep 26 12:37:12 2010
@@ -1713,7 +1713,14 @@
 if (m && m->nb_long) { /* This should include subclasses of long */
 /* Classic classes always take this branch. */
 PyObject *res = m->nb_long(o);
- if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
+ if (res == NULL)
+ return NULL;
+ if (PyInt_Check(res)) {
+ long value = PyInt_AS_LONG(res);
+ Py_DECREF(res);
+ return PyLong_FromLong(value);
+ }
+ else if (!PyLong_Check(res)) {
 PyErr_Format(PyExc_TypeError,
 "__long__ returned non-long (type %.200s)",
 res->ob_type->tp_name);


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /