Kaydet (Commit) af685f90 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka Kaydeden (comit) GitHub

bpo-29998: Pickling and copying ImportError now preserves name and path (#1010) (#1042)

attributes.
(cherry picked from commit b785396a)
üst c26b19d5
# Python test set -- part 5, built-in exceptions
import copy
import os
import sys
import unittest
......@@ -1119,6 +1120,25 @@ class ImportErrorTests(unittest.TestCase):
exc = ImportError(arg)
self.assertEqual(str(arg), str(exc))
def test_copy_pickle(self):
for kwargs in (dict(),
dict(name='somename'),
dict(path='somepath'),
dict(name='somename', path='somepath')):
orig = ImportError('test', **kwargs)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
exc = pickle.loads(pickle.dumps(orig, proto))
self.assertEqual(exc.args, ('test',))
self.assertEqual(exc.msg, 'test')
self.assertEqual(exc.name, orig.name)
self.assertEqual(exc.path, orig.path)
for c in copy.copy, copy.deepcopy:
exc = c(orig)
self.assertEqual(exc.args, ('test',))
self.assertEqual(exc.msg, 'test')
self.assertEqual(exc.name, orig.name)
self.assertEqual(exc.path, orig.path)
if __name__ == '__main__':
unittest.main()
......@@ -32,6 +32,9 @@ Core and Builtins
Library
-------
- bpo-29998: Pickling and copying ImportError now preserves name and path
attributes.
- bpo-29953: Fixed memory leaks in the replace() method of datetime and time
objects when pass out of bound fold argument.
......
......@@ -686,6 +686,53 @@ ImportError_str(PyImportErrorObject *self)
}
}
static PyObject *
ImportError_getstate(PyImportErrorObject *self)
{
PyObject *dict = ((PyBaseExceptionObject *)self)->dict;
if (self->name || self->path) {
_Py_IDENTIFIER(name);
_Py_IDENTIFIER(path);
dict = dict ? PyDict_Copy(dict) : PyDict_New();
if (dict == NULL)
return NULL;
if (self->name && _PyDict_SetItemId(dict, &PyId_name, self->name) < 0) {
Py_DECREF(dict);
return NULL;
}
if (self->path && _PyDict_SetItemId(dict, &PyId_path, self->path) < 0) {
Py_DECREF(dict);
return NULL;
}
return dict;
}
else if (dict) {
Py_INCREF(dict);
return dict;
}
else {
Py_RETURN_NONE;
}
}
/* Pickling support */
static PyObject *
ImportError_reduce(PyImportErrorObject *self)
{
PyObject *res;
PyObject *args;
PyObject *state = ImportError_getstate(self);
if (state == NULL)
return NULL;
args = ((PyBaseExceptionObject *)self)->args;
if (state == Py_None)
res = PyTuple_Pack(2, Py_TYPE(self), args);
else
res = PyTuple_Pack(3, Py_TYPE(self), args, state);
Py_DECREF(state);
return res;
}
static PyMemberDef ImportError_members[] = {
{"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0,
PyDoc_STR("exception message")},
......@@ -697,6 +744,7 @@ static PyMemberDef ImportError_members[] = {
};
static PyMethodDef ImportError_methods[] = {
{"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS},
{NULL}
};
......
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