]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-66143: Allow copying and pickling of CodecInfo object (GH-109235)
authorFurkan Onder <furkanonder@protonmail.com>
Fri, 29 Sep 2023 17:07:09 +0000 (20:07 +0300)
committerGitHub <noreply@github.com>
Fri, 29 Sep 2023 17:07:09 +0000 (20:07 +0300)
Co-authored-by: Robert Lehmann <mail@robertlehmann.de>
Lib/codecs.py
Lib/test/test_codecs.py
Misc/NEWS.d/next/Library/2023-09-10-20-23-20.gh-issue-66143.71xvgL.rst [new file with mode: 0644]

index 82f23983e719c23f1715dde3d10faa1db673002a..9b35b6127dd01c77fc61f3f166c6985798b7359f 100644 (file)
@@ -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.
index b5e9271ac0c3cdca98f31497ac7a5a571ee87825..c899111e1e4c16bfa18240d9954c691e61f0ae45 100644 (file)
@@ -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 (file)
index 0000000..2769c05
--- /dev/null
@@ -0,0 +1,2 @@
+The :class:`codecs.CodecInfo` object has been made copyable and pickleable.
+Patched by Robert Lehmann and Furkan Onder.