mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Merged revisions 79674 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r79674 | mark.dickinson | 2010-04-03 15:05:10 +0100 (Sat, 03 Apr 2010) | 3 lines Issue #8300: Let struct.pack use __index__ to convert and pack non-integers. Based on a patch by Meador Inge. ........
This commit is contained in:
parent
089b00cbc3
commit
c593577a4a
4 changed files with 50 additions and 4 deletions
|
@ -119,6 +119,15 @@ Notes:
|
||||||
the platform C compiler supports C :ctype:`long long`, or, on Windows,
|
the platform C compiler supports C :ctype:`long long`, or, on Windows,
|
||||||
:ctype:`__int64`. They are always available in standard modes.
|
:ctype:`__int64`. They are always available in standard modes.
|
||||||
|
|
||||||
|
(4)
|
||||||
|
When attempting to pack a non-integer using any of the integer conversion
|
||||||
|
codes, if the non-integer has a :meth:`__index__` method then that method is
|
||||||
|
called to convert the argument to an integer before packing.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.2
|
||||||
|
Use of the :meth:`__index__` method for non-integers is new in 3.2.
|
||||||
|
|
||||||
|
|
||||||
A format character may be preceded by an integral repeat count. For example,
|
A format character may be preceded by an integral repeat count. For example,
|
||||||
the format string ``'4h'`` means exactly the same as ``'hhhh'``.
|
the format string ``'4h'`` means exactly the same as ``'hhhh'``.
|
||||||
|
|
||||||
|
|
|
@ -282,6 +282,23 @@ class StructTest(unittest.TestCase):
|
||||||
struct.pack, self.format,
|
struct.pack, self.format,
|
||||||
NotAnInt)
|
NotAnInt)
|
||||||
|
|
||||||
|
# Objects with an '__index__' method should be allowed
|
||||||
|
# to pack as integers.
|
||||||
|
class Indexable(object):
|
||||||
|
def __init__(self, value):
|
||||||
|
self._value = value
|
||||||
|
|
||||||
|
def __index__(self):
|
||||||
|
return self._value
|
||||||
|
|
||||||
|
for obj in (Indexable(0), Indexable(10), Indexable(17),
|
||||||
|
Indexable(42), Indexable(100), Indexable(127)):
|
||||||
|
try:
|
||||||
|
struct.pack(format, obj)
|
||||||
|
except:
|
||||||
|
self.fail("integer code pack failed on object "
|
||||||
|
"with '__index__' method")
|
||||||
|
|
||||||
for code in integer_codes:
|
for code in integer_codes:
|
||||||
for byteorder in byteorders:
|
for byteorder in byteorders:
|
||||||
if (byteorder in ('', '@') and code in ('q', 'Q') and
|
if (byteorder in ('', '@') and code in ('q', 'Q') and
|
||||||
|
|
|
@ -879,6 +879,11 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #8300: When passing a non-integer argument to struct.pack with any
|
||||||
|
integer format code, struct.pack first attempts to convert the non-integer
|
||||||
|
using its __index__ method. If that method is non-existent or raises
|
||||||
|
TypeError it goes on to try the __int__ method, as described below.
|
||||||
|
|
||||||
- Issue #8142: Update libffi to the 3.0.9 release.
|
- Issue #8142: Update libffi to the 3.0.9 release.
|
||||||
|
|
||||||
- Issue #6949: Allow the _dbm extension to be built with db 4.8.x.
|
- Issue #6949: Allow the _dbm extension to be built with db 4.8.x.
|
||||||
|
|
|
@ -97,12 +97,27 @@ get_pylong(PyObject *v)
|
||||||
{
|
{
|
||||||
assert(v != NULL);
|
assert(v != NULL);
|
||||||
if (!PyLong_Check(v)) {
|
if (!PyLong_Check(v)) {
|
||||||
PyErr_SetString(StructError,
|
/* Not an integer; try to use __index__ to convert. */
|
||||||
"required argument is not an integer");
|
if (PyIndex_Check(v)) {
|
||||||
return NULL;
|
v = PyNumber_Index(v);
|
||||||
|
if (v == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (!PyLong_Check(v)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"__index__ method "
|
||||||
|
"returned non-integer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_SetString(StructError,
|
||||||
|
"required argument is not an integer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Py_INCREF(v);
|
||||||
|
|
||||||
Py_INCREF(v);
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue