bpo-41919: Avoid resource leak in test_io (GH-22973)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index fbaea3a..cc54d0e 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -2519,15 +2519,17 @@ def process_word(self):
 
     codecEnabled = False
 
-    @classmethod
-    def lookupTestDecoder(cls, name):
-        if cls.codecEnabled and name == 'test_decoder':
-            latin1 = codecs.lookup('latin-1')
-            return codecs.CodecInfo(
-                name='test_decoder', encode=latin1.encode, decode=None,
-                incrementalencoder=None,
-                streamreader=None, streamwriter=None,
-                incrementaldecoder=cls)
+
+# bpo-41919: This method is separated from StatefulIncrementalDecoder to avoid a resource leak
+# when registering codecs and cleanup functions.
+def lookupTestDecoder(name):
+    if StatefulIncrementalDecoder.codecEnabled and name == 'test_decoder':
+        latin1 = codecs.lookup('latin-1')
+        return codecs.CodecInfo(
+            name='test_decoder', encode=latin1.encode, decode=None,
+            incrementalencoder=None,
+            streamreader=None, streamwriter=None,
+            incrementaldecoder=StatefulIncrementalDecoder)
 
 
 class StatefulIncrementalDecoderTest(unittest.TestCase):
@@ -2579,9 +2581,8 @@ def setUp(self):
         self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n"
         self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii")
         os_helper.unlink(os_helper.TESTFN)
-        codecs.register(StatefulIncrementalDecoder.lookupTestDecoder)
-        self.addCleanup(codecs.unregister,
-                        StatefulIncrementalDecoder.lookupTestDecoder)
+        codecs.register(lookupTestDecoder)
+        self.addCleanup(codecs.unregister, lookupTestDecoder)
 
     def tearDown(self):
         os_helper.unlink(os_helper.TESTFN)