Skip to content

Commit 3439cb0

Browse files
pythongh-66143: Allow copying and pickling of CodecInfo object (pythonGH-109235)
Co-authored-by: Robert Lehmann <[email protected]>
1 parent 7d57288 commit 3439cb0

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

Lib/codecs.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ def __repr__(self):
111111
(self.__class__.__module__, self.__class__.__qualname__,
112112
self.name, id(self))
113113

114+
def __getnewargs__(self):
115+
return tuple(self)
116+
114117
class Codec:
115118

116119
""" Defines the interface for stateless encoders/decoders.

Lib/test/test_codecs.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,76 @@ def test_file_closes_if_lookup_error_raised(self):
17621762

17631763
file().close.assert_called()
17641764

1765+
def test_copy(self):
1766+
orig = codecs.lookup('utf-8')
1767+
dup = copy.copy(orig)
1768+
self.assertIsNot(dup, orig)
1769+
self.assertEqual(dup, orig)
1770+
self.assertTrue(orig._is_text_encoding)
1771+
self.assertEqual(dup.encode, orig.encode)
1772+
self.assertEqual(dup.name, orig.name)
1773+
self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
1774+
1775+
# Test a CodecInfo with _is_text_encoding equal to false.
1776+
orig = codecs.lookup("base64")
1777+
dup = copy.copy(orig)
1778+
self.assertIsNot(dup, orig)
1779+
self.assertEqual(dup, orig)
1780+
self.assertFalse(orig._is_text_encoding)
1781+
self.assertEqual(dup.encode, orig.encode)
1782+
self.assertEqual(dup.name, orig.name)
1783+
self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
1784+
1785+
def test_deepcopy(self):
1786+
orig = codecs.lookup('utf-8')
1787+
dup = copy.deepcopy(orig)
1788+
self.assertIsNot(dup, orig)
1789+
self.assertEqual(dup, orig)
1790+
self.assertTrue(orig._is_text_encoding)
1791+
self.assertEqual(dup.encode, orig.encode)
1792+
self.assertEqual(dup.name, orig.name)
1793+
self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
1794+
1795+
# Test a CodecInfo with _is_text_encoding equal to false.
1796+
orig = codecs.lookup("base64")
1797+
dup = copy.deepcopy(orig)
1798+
self.assertIsNot(dup, orig)
1799+
self.assertEqual(dup, orig)
1800+
self.assertFalse(orig._is_text_encoding)
1801+
self.assertEqual(dup.encode, orig.encode)
1802+
self.assertEqual(dup.name, orig.name)
1803+
self.assertEqual(dup.incrementalencoder, orig.incrementalencoder)
1804+
1805+
def test_pickle(self):
1806+
codec_info = codecs.lookup('utf-8')
1807+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1808+
with self.subTest(protocol=proto):
1809+
pickled_codec_info = pickle.dumps(codec_info)
1810+
unpickled_codec_info = pickle.loads(pickled_codec_info)
1811+
self.assertIsNot(codec_info, unpickled_codec_info)
1812+
self.assertEqual(codec_info, unpickled_codec_info)
1813+
self.assertEqual(codec_info.name, unpickled_codec_info.name)
1814+
self.assertEqual(
1815+
codec_info.incrementalencoder,
1816+
unpickled_codec_info.incrementalencoder
1817+
)
1818+
self.assertTrue(unpickled_codec_info._is_text_encoding)
1819+
1820+
# Test a CodecInfo with _is_text_encoding equal to false.
1821+
codec_info = codecs.lookup('base64')
1822+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1823+
with self.subTest(protocol=proto):
1824+
pickled_codec_info = pickle.dumps(codec_info)
1825+
unpickled_codec_info = pickle.loads(pickled_codec_info)
1826+
self.assertIsNot(codec_info, unpickled_codec_info)
1827+
self.assertEqual(codec_info, unpickled_codec_info)
1828+
self.assertEqual(codec_info.name, unpickled_codec_info.name)
1829+
self.assertEqual(
1830+
codec_info.incrementalencoder,
1831+
unpickled_codec_info.incrementalencoder
1832+
)
1833+
self.assertFalse(unpickled_codec_info._is_text_encoding)
1834+
17651835

17661836
class StreamReaderTest(unittest.TestCase):
17671837

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The :class:`codecs.CodecInfo` object has been made copyable and pickleable.
2+
Patched by Robert Lehmann and Furkan Onder.

0 commit comments

Comments
 (0)