Kaydet (Commit) 1c0c78c6 authored tarafından Mark Dickinson's avatar Mark Dickinson

Fix incorrect stacklevel for DeprecationWarnings originating from the struct module.

Also clean up related tests in test_struct.
The stacklevel fix should be backported to 2.6 once that branch is unfrozen.
üst 3bbb6727
...@@ -23,13 +23,6 @@ except struct.error: ...@@ -23,13 +23,6 @@ except struct.error:
else: else:
HAVE_LONG_LONG = True HAVE_LONG_LONG = True
try:
import _struct
except ImportError:
PY_STRUCT_FLOAT_COERCE = 2
else:
PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0)
def string_reverse(s): def string_reverse(s):
return "".join(reversed(s)) return "".join(reversed(s))
...@@ -39,39 +32,25 @@ def bigendian_to_native(value): ...@@ -39,39 +32,25 @@ def bigendian_to_native(value):
else: else:
return string_reverse(value) return string_reverse(value)
def with_warning_restore(func):
@wraps(func)
def decorator(*args, **kw):
with warnings.catch_warnings():
# We need this function to warn every time, so stick an
# unqualifed 'always' at the head of the filter list
warnings.simplefilter("always")
warnings.filterwarnings("error", category=DeprecationWarning)
return func(*args, **kw)
return decorator
class StructTest(unittest.TestCase): class StructTest(unittest.TestCase):
@with_warning_restore
def check_float_coerce(self, format, number): def check_float_coerce(self, format, number):
# SF bug 1530559. struct.pack raises TypeError where it used to convert. # SF bug 1530559. struct.pack raises TypeError where it used to convert.
if PY_STRUCT_FLOAT_COERCE == 2: with warnings.catch_warnings():
# Test for pre-2.5 struct module warnings.filterwarnings(
packed = struct.pack(format, number) "ignore",
floored = struct.unpack(format, packed)[0] category=DeprecationWarning,
self.assertEqual(floored, int(number), message=".*integer argument expected, got float",
"did not correcly coerce float to int") module=__name__)
return self.assertEqual(struct.pack(format, number), struct.pack(format, int(number)))
try:
struct.pack(format, number) with warnings.catch_warnings():
except struct.error: warnings.filterwarnings(
if PY_STRUCT_FLOAT_COERCE: "error",
self.fail("expected DeprecationWarning for float coerce") category=DeprecationWarning,
except DeprecationWarning: message=".*integer argument expected, got float",
if not PY_STRUCT_FLOAT_COERCE: module="unittest")
self.fail("expected to raise struct.error for float coerce") self.assertRaises(DeprecationWarning, struct.pack, format, number)
else:
self.fail("did not raise error for float coerce")
def test_isbigendian(self): def test_isbigendian(self):
self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN) self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN)
......
...@@ -121,7 +121,7 @@ get_pylong(PyObject *v) ...@@ -121,7 +121,7 @@ get_pylong(PyObject *v)
} }
#ifdef PY_STRUCT_FLOAT_COERCE #ifdef PY_STRUCT_FLOAT_COERCE
if (PyFloat_Check(v)) { if (PyFloat_Check(v)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2)<0) if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 1)<0)
return NULL; return NULL;
return PyNumber_Long(v); return PyNumber_Long(v);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment