summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/codecs.py3
-rw-r--r--Lib/test/test_codecs.py70
-rw-r--r--Misc/NEWS.d/next/Library/2023-09-10-20-23-20.gh-issue-66143.71xvgL.rst2
3 files changed, 75 insertions, 0 deletions
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 82f2398..9b35b61 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -111,6 +111,9 @@ class CodecInfo(tuple):
(self.__class__.__module__, self.__class__.__qualname__,
self.name, id(self))
+ def __getnewargs__(self):
+ return tuple(self)
+
class Codec:
""" Defines the interface for stateless encoders/decoders.
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index b5e9271..c899111 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -1762,6 +1762,76 @@ class CodecsModuleTest(unittest.TestCase):
file().close.assert_called()
+ def test_copy(self):
+ orig = codecs.lookup('utf-8')
+ dup = copy.copy(orig)
+ self.assertIsNot(dup, orig)
+ self.assertEqual(dup, orig)
+ self.assertTrue(orig._is_text_encoding)
+ self.assertEqual(dup.encode, orig.encode)
+ self.assertEqual(dup.name, orig.name)
+ self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
+
+ # Test a CodecInfo with _is_text_encoding equal to false.
+ orig = codecs.lookup("base64")
+ dup = copy.copy(orig)
+ self.assertIsNot(dup, orig)
+ self.assertEqual(dup, orig)
+ self.assertFalse(orig._is_text_encoding)
+ self.assertEqual(dup.encode, orig.encode)
+ self.assertEqual(dup.name, orig.name)
+ self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
+
+ def test_deepcopy(self):
+ orig = codecs.lookup('utf-8')
+ dup = copy.deepcopy(orig)
+ self.assertIsNot(dup, orig)
+ self.assertEqual(dup, orig)
+ self.assertTrue(orig._is_text_encoding)
+ self.assertEqual(dup.encode, orig.encode)
+ self.assertEqual(dup.name, orig.name)
+ self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
+
+ # Test a CodecInfo with _is_text_encoding equal to false.
+ orig = codecs.lookup("base64")
+ dup = copy.deepcopy(orig)
+ self.assertIsNot(dup, orig)
+ self.assertEqual(dup, orig)
+ self.assertFalse(orig._is_text_encoding)
+ self.assertEqual(dup.encode, orig.encode)
+ self.assertEqual(dup.name, orig.name)
+ self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
+
+ def test_pickle(self):
+ codec_info = codecs.lookup('utf-8')
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.subTest(protocol=proto):
+ pickled_codec_info = pickle.dumps(codec_info)
+ unpickled_codec_info = pickle.loads(pickled_codec_info)
+ self.assertIsNot(codec_info, unpickled_codec_info)
+ self.assertEqual(codec_info, unpickled_codec_info)
+ self.assertEqual(codec_info.name, unpickled_codec_info.name)
+ self.assertEqual(
+ codec_info.incrementalencoder,
+ unpickled_codec_info.incrementalencoder
+ )
+ self.assertTrue(unpickled_codec_info._is_text_encoding)
+
+ # Test a CodecInfo with _is_text_encoding equal to false.
+ codec_info = codecs.lookup('base64')
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.subTest(protocol=proto):
+ pickled_codec_info = pickle.dumps(codec_info)
+ unpickled_codec_info = pickle.loads(pickled_codec_info)
+ self.assertIsNot(codec_info, unpickled_codec_info)
+ self.assertEqual(codec_info, unpickled_codec_info)
+ self.assertEqual(codec_info.name, unpickled_codec_info.name)
+ self.assertEqual(
+ codec_info.incrementalencoder,
+ unpickled_codec_info.incrementalencoder
+ )
+ self.assertFalse(unpickled_codec_info._is_text_encoding)
+
class StreamReaderTest(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2023-09-10-20-23-20.gh-issue-66143.71xvgL.rst b/Misc/NEWS.d/next/Library/2023-09-10-20-23-20.gh-issue-66143.71xvgL.rst
new file mode 100644
index 0000000..2769c05
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-10-20-23-20.gh-issue-66143.71xvgL.rst
@@ -0,0 +1,2 @@
+The :class:`codecs.CodecInfo` object has been made copyable and pickleable.
+Patched by Robert Lehmann and Furkan Onder.