Add a test case for exception pickling. args is never NULL.
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 076d84d..b4a766e 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -270,6 +270,8 @@
'winerror' : 1 }))
except NameError: pass
+import pickle, random
+
for args in exceptionList:
expected = args[-1]
try:
@@ -283,3 +285,14 @@
( repr(e), checkArgName,
repr(expected[checkArgName]),
repr(getattr(e, checkArgName)) ))
+
+ # test for pickling support
+ new = pickle.loads(pickle.dumps(e, random.randint(0, 2)))
+ for checkArgName in expected.keys():
+ if repr(getattr(e, checkArgName)) != repr(expected[checkArgName]):
+ raise TestFailed('Checking unpickled exception arguments, '
+ 'exception '
+ '"%s", attribute "%s" expected %s got %s.' %
+ ( repr(e), checkArgName,
+ repr(expected[checkArgName]),
+ repr(getattr(e, checkArgName)) ))
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 986d211..16ba5e5 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -143,15 +143,8 @@
{
if (self->args && self->dict)
return PyTuple_Pack(3, self->ob_type, self->args, self->dict);
- else if (self->args)
+ else
return PyTuple_Pack(2, self->ob_type, self->args);
- else {
- PyObject *res, *tup = PyTuple_New(0);
- if (!tup) return NULL;
- res = PyTuple_Pack(2, self->ob_type, tup);
- Py_DECREF(tup);
- return res;
- }
}
@@ -667,6 +660,7 @@
{
PyObject *args = self->args;
PyObject *res = NULL, *tmp;
+
/* self->args is only the first two real arguments if there was a
* file name given to EnvironmentError. */
if (PyTuple_GET_SIZE(args) == 2 && self->filename) {
@@ -683,10 +677,13 @@
Py_INCREF(self->filename);
PyTuple_SET_ITEM(args, 2, self->filename);
- } else {
+ } else
Py_INCREF(args);
- }
- res = PyTuple_Pack(3, self->ob_type, args, self->dict);
+
+ if (self->dict)
+ res = PyTuple_Pack(3, self->ob_type, args, self->dict);
+ else
+ res = PyTuple_Pack(2, self->ob_type, args);
Py_DECREF(args);
return res;
}