From d516afb5f6bb994f699d212927a8cea085be79b5 Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 20:33:26 -0400 Subject: [PATCH 1/6] Add BaseException.__reduce__ --- vm/src/exceptions.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 272251591e5..226c0d94231 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -2,7 +2,8 @@ use self::types::{PyBaseException, PyBaseExceptionRef}; use crate::common::lock::PyRwLock; use crate::{ builtins::{ - traceback::PyTracebackRef, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, + traceback::PyTracebackRef, PyDictRef, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, + PyTypeRef, }, class::{PyClassImpl, StaticType}, convert::{ToPyException, ToPyObject}, @@ -519,6 +520,18 @@ impl PyBaseException { let cls = zelf.class(); format!("{}({})", cls.name(), repr_args.iter().format(", ")) } + + #[pymethod(magic)] + fn reduce( + zelf: PyRef, + _vm: &VirtualMachine, + ) -> (PyTypeRef, PyTupleRef, Option) { + ( + zelf.class().clone(), + zelf.args().clone(), + zelf.as_object().dict(), + ) + } } impl ExceptionZoo { From 2815f3d037db62d8cdcd08b98bb5703968d13dd4 Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 20:40:06 -0400 Subject: [PATCH 2/6] Unmark passing test --- Lib/test/test_exceptions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 8a67c51bde3..b3e3897ca36 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1923,8 +1923,6 @@ def test_non_str_argument(self): exc = ImportError(arg) self.assertEqual(str(arg), str(exc)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_copy_pickle(self): for kwargs in (dict(), dict(name='somename'), From 9d898deaedb237b37fdfc74691958d5e24828aa6 Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 21:29:42 -0400 Subject: [PATCH 3/6] Fix Clippy warning --- vm/src/exceptions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 226c0d94231..99122adf01d 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -528,7 +528,7 @@ impl PyBaseException { ) -> (PyTypeRef, PyTupleRef, Option) { ( zelf.class().clone(), - zelf.args().clone(), + zelf.args(), zelf.as_object().dict(), ) } From d51593d50bc38b46335e9e5dbd77a5ad5209a5f8 Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 21:44:13 -0400 Subject: [PATCH 4/6] Run rustfmt --- vm/src/exceptions.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 99122adf01d..be17ffbd6f3 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -526,11 +526,7 @@ impl PyBaseException { zelf: PyRef, _vm: &VirtualMachine, ) -> (PyTypeRef, PyTupleRef, Option) { - ( - zelf.class().clone(), - zelf.args(), - zelf.as_object().dict(), - ) + (zelf.class().clone(), zelf.args(), zelf.as_object().dict()) } } From e2af440af1b0735426432d01c9276ccf7fe46181 Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 22:50:19 -0400 Subject: [PATCH 5/6] Add case where exception dict is empty or missing --- vm/src/exceptions.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index be17ffbd6f3..6fe2da677ef 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -2,8 +2,7 @@ use self::types::{PyBaseException, PyBaseExceptionRef}; use crate::common::lock::PyRwLock; use crate::{ builtins::{ - traceback::PyTracebackRef, PyDictRef, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, - PyTypeRef, + traceback::PyTracebackRef, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, }, class::{PyClassImpl, StaticType}, convert::{ToPyException, ToPyObject}, @@ -522,11 +521,12 @@ impl PyBaseException { } #[pymethod(magic)] - fn reduce( - zelf: PyRef, - _vm: &VirtualMachine, - ) -> (PyTypeRef, PyTupleRef, Option) { - (zelf.class().clone(), zelf.args(), zelf.as_object().dict()) + fn reduce(zelf: PyRef, vm: &VirtualMachine) -> PyTupleRef { + if let Some(dict) = zelf.as_object().dict().filter(|x| !x.is_empty()) { + return vm.new_tuple((zelf.class().clone(), zelf.args(), dict)); + } else { + return vm.new_tuple((zelf.class().clone(), zelf.args())); + } } } From dfbd8dc8db50d7a31aec10c1472a2cff14a3d30b Mon Sep 17 00:00:00 2001 From: Padraic Fanning Date: Wed, 27 Apr 2022 22:56:24 -0400 Subject: [PATCH 6/6] Unmark passing tests --- Lib/test/test_configparser.py | 22 ---------------------- Lib/unittest/test/test_discovery.py | 2 -- 2 files changed, 24 deletions(-) diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index d2cfd08cc89..84499689e12 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1703,8 +1703,6 @@ def test_inconsistent_converters_state(self): class ExceptionPicklingTestCase(unittest.TestCase): """Tests for issue #13760: ConfigParser exceptions are not picklable.""" - # TODO: RUSTPYTHON Exception.__reduce__ missing. - @unittest.expectedFailure def test_error(self): import pickle e1 = configparser.Error('value') @@ -1714,8 +1712,6 @@ def test_error(self): self.assertEqual(e1.message, e2.message) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_nosectionerror(self): import pickle e1 = configparser.NoSectionError('section') @@ -1727,8 +1723,6 @@ def test_nosectionerror(self): self.assertEqual(e1.section, e2.section) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_nooptionerror(self): import pickle e1 = configparser.NoOptionError('option', 'section') @@ -1741,8 +1735,6 @@ def test_nooptionerror(self): self.assertEqual(e1.option, e2.option) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_duplicatesectionerror(self): import pickle e1 = configparser.DuplicateSectionError('section', 'source', 123) @@ -1756,8 +1748,6 @@ def test_duplicatesectionerror(self): self.assertEqual(e1.lineno, e2.lineno) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_duplicateoptionerror(self): import pickle e1 = configparser.DuplicateOptionError('section', 'option', 'source', @@ -1773,8 +1763,6 @@ def test_duplicateoptionerror(self): self.assertEqual(e1.lineno, e2.lineno) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_interpolationerror(self): import pickle e1 = configparser.InterpolationError('option', 'section', 'msg') @@ -1787,8 +1775,6 @@ def test_interpolationerror(self): self.assertEqual(e1.option, e2.option) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_interpolationmissingoptionerror(self): import pickle e1 = configparser.InterpolationMissingOptionError('option', 'section', @@ -1803,8 +1789,6 @@ def test_interpolationmissingoptionerror(self): self.assertEqual(e1.reference, e2.reference) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_interpolationsyntaxerror(self): import pickle e1 = configparser.InterpolationSyntaxError('option', 'section', 'msg') @@ -1817,8 +1801,6 @@ def test_interpolationsyntaxerror(self): self.assertEqual(e1.option, e2.option) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_interpolationdeptherror(self): import pickle e1 = configparser.InterpolationDepthError('option', 'section', @@ -1832,8 +1814,6 @@ def test_interpolationdeptherror(self): self.assertEqual(e1.option, e2.option) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_parsingerror(self): import pickle e1 = configparser.ParsingError('source') @@ -1861,8 +1841,6 @@ def test_parsingerror(self): self.assertEqual(e1.errors, e2.errors) self.assertEqual(repr(e1), repr(e2)) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_missingsectionheadererror(self): import pickle e1 = configparser.MissingSectionHeaderError('filename', 123, 'line') diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 16d2f76a8c7..a4193d71bad 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -499,8 +499,6 @@ def test_discover_with_modules_that_fail_to_import(self): with self.assertRaises(ImportError): test.test_this_does_not_exist() - # TODO: RUSTPYTHON ImportError.__reduce__ missing - @unittest.expectedFailure def test_discover_with_init_modules_that_fail_to_import(self): vfs = {abspath('/foo'): ['my_package'], abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}