From d003a5bd2505a7fa04f50504b68ba8fca67349cd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 8 Sep 2021 13:07:40 +0300 Subject: [PATCH] bpo-45132 Remove deprecated __getitem__ methods (GH-28225) Remove deprecated __getitem__ methods of xml.dom.pulldom.DOMEventStream, wsgiref.util.FileWrapper and fileinput.FileInput, deprecated since Python 3.9. --- Doc/library/fileinput.rst | 15 +++--- Doc/library/wsgiref.rst | 7 ++- Doc/library/xml.dom.pulldom.rst | 5 +- Doc/whatsnew/3.11.rst | 6 +++ Lib/fileinput.py | 15 ------ Lib/test/test_fileinput.py | 39 --------------- Lib/test/test_pulldom.py | 7 --- Lib/test/test_wsgiref.py | 48 +++++-------------- Lib/wsgiref/util.py | 13 ----- Lib/xml/dom/pulldom.py | 13 ----- .../2021-09-07-16-33-51.bpo-45132.WI9zQY.rst | 5 ++ 11 files changed, 34 insertions(+), 139 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-09-07-16-33-51.bpo-45132.WI9zQY.rst diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 9f7802dd456..731c3d0c99a 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -146,11 +146,10 @@ available for subclassing as well: Class :class:`FileInput` is the implementation; its methods :meth:`filename`, :meth:`fileno`, :meth:`lineno`, :meth:`filelineno`, :meth:`isfirstline`, :meth:`isstdin`, :meth:`nextfile` and :meth:`close` correspond to the - functions of the same name in the module. In addition it has a - :meth:`~io.TextIOBase.readline` method which returns the next input line, - and a :meth:`__getitem__` method which implements the sequence behavior. - The sequence must be accessed in strictly sequential order; random access - and :meth:`~io.TextIOBase.readline` cannot be mixed. + functions of the same name in the module. In addition it is :term:`iterable` + and has a :meth:`~io.TextIOBase.readline` method which returns the next + input line. The sequence must be accessed in strictly sequential order; + random access and :meth:`~io.TextIOBase.readline` cannot be mixed. With *mode* you can specify which file mode will be passed to :func:`open`. It must be one of ``'r'`` and ``'rb'``. @@ -171,9 +170,6 @@ available for subclassing as well: .. versionchanged:: 3.2 Can be used as a context manager. - .. deprecated:: 3.8 - Support for :meth:`__getitem__` method is deprecated. - .. versionchanged:: 3.8 The keyword parameter *mode* and *openhook* are now keyword-only. @@ -181,7 +177,8 @@ available for subclassing as well: The keyword-only parameter *encoding* and *errors* are added. .. versionchanged:: 3.11 - The ``'rU'`` and ``'U'`` modes have been removed. + The ``'rU'`` and ``'U'`` modes and the :meth:`__getitem__` method have + been removed. **Optional in-place filtering:** if the keyword argument ``inplace=True`` is diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index e92a689de0b..5454b1132d2 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -151,8 +151,7 @@ also provides these miscellaneous utilities: .. class:: FileWrapper(filelike, blksize=8192) A wrapper to convert a file-like object to an :term:`iterator`. The resulting objects - support both :meth:`__getitem__` and :meth:`__iter__` iteration styles, for - compatibility with Python 2.1 and Jython. As the object is iterated over, the + are :term`iterable`\ s. As the object is iterated over, the optional *blksize* parameter will be repeatedly passed to the *filelike* object's :meth:`read` method to obtain bytestrings to yield. When :meth:`read` returns an empty bytestring, iteration is ended and is not resumable. @@ -173,8 +172,8 @@ also provides these miscellaneous utilities: for chunk in wrapper: print(chunk) - .. deprecated:: 3.8 - Support for :meth:`sequence protocol <__getitem__>` is deprecated. + .. versionchanged:: 3.11 + Support for :meth:`__getitem__` method has been removed. :mod:`wsgiref.headers` -- WSGI response header tools diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index 660c75c1a1b..d1df465a598 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -114,8 +114,8 @@ DOMEventStream Objects .. class:: DOMEventStream(stream, parser, bufsize) - .. deprecated:: 3.8 - Support for :meth:`sequence protocol <__getitem__>` is deprecated. + .. versionchanged:: 3.11 + Support for :meth:`__getitem__` method has been removed. .. method:: getEvent() @@ -144,4 +144,3 @@ DOMEventStream Objects print(node.toxml()) .. method:: DOMEventStream.reset() - diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 30ee182718d..55ba8329a1f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -254,6 +254,12 @@ Removed Use ``bdist_wheel`` (wheel packages) instead. (Contributed by Hugo van Kemenade in :issue:`45124`.) +* Remove :meth:`__getitem__` methods of + :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` + and :class:`fileinput.FileInput`, deprecated since Python 3.9. + (Contributed by Hugo van Kemenade in :issue:`45132`.) + + Optimizations ============= diff --git a/Lib/fileinput.py b/Lib/fileinput.py index d0b3caae5d6..9f41c18510d 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -257,21 +257,6 @@ def __next__(self): self.nextfile() # repeat with next file - def __getitem__(self, i): - import warnings - warnings.warn( - "Support for indexing FileInput objects is deprecated. " - "Use iterator protocol instead.", - DeprecationWarning, - stacklevel=2 - ) - if i != self.lineno(): - raise RuntimeError("accessing lines out of order") - try: - return self.__next__() - except StopIteration: - raise IndexError("end of input reached") - def nextfile(self): savestdout = self._savestdout self._savestdout = None diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index 31684aefdb0..819200010a2 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -29,7 +29,6 @@ from test.support.os_helper import TESTFN from test.support.os_helper import unlink as safe_unlink from test.support import os_helper -from test.support import warnings_helper from test import support from unittest import mock @@ -357,44 +356,6 @@ def test_empty_files_list_specified_to_constructor(self): with FileInput(files=[], encoding="utf-8") as fi: self.assertEqual(fi._files, ('-',)) - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test__getitem__(self): - """Tests invoking FileInput.__getitem__() with the current - line number""" - t = self.writeTmp("line1\nline2\n") - with FileInput(files=[t], encoding="utf-8") as fi: - retval1 = fi[0] - self.assertEqual(retval1, "line1\n") - retval2 = fi[1] - self.assertEqual(retval2, "line2\n") - - def test__getitem___deprecation(self): - t = self.writeTmp("line1\nline2\n") - with self.assertWarnsRegex(DeprecationWarning, - r'Use iterator protocol instead'): - with FileInput(files=[t]) as fi: - self.assertEqual(fi[0], "line1\n") - - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test__getitem__invalid_key(self): - """Tests invoking FileInput.__getitem__() with an index unequal to - the line number""" - t = self.writeTmp("line1\nline2\n") - with FileInput(files=[t], encoding="utf-8") as fi: - with self.assertRaises(RuntimeError) as cm: - fi[1] - self.assertEqual(cm.exception.args, ("accessing lines out of order",)) - - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test__getitem__eof(self): - """Tests invoking FileInput.__getitem__() with the line number but at - end-of-input""" - t = self.writeTmp('') - with FileInput(files=[t], encoding="utf-8") as fi: - with self.assertRaises(IndexError) as cm: - fi[0] - self.assertEqual(cm.exception.args, ("end of input reached",)) - def test_nextfile_oserror_deleting_backup(self): """Tests invoking FileInput.nextfile() when the attempt to delete the backup file would raise OSError. This error is expected to be diff --git a/Lib/test/test_pulldom.py b/Lib/test/test_pulldom.py index 4a1bad3442b..6dc51e4371d 100644 --- a/Lib/test/test_pulldom.py +++ b/Lib/test/test_pulldom.py @@ -160,13 +160,6 @@ def test_end_document(self): self.fail( "Ran out of events, but should have received END_DOCUMENT") - def test_getitem_deprecation(self): - parser = pulldom.parseString(SMALL_SAMPLE) - with self.assertWarnsRegex(DeprecationWarning, - r'Use iterator protocol instead'): - # This should have returned 'END_ELEMENT'. - self.assertEqual(parser[-1][0], pulldom.START_DOCUMENT) - def test_external_ges_default(self): parser = pulldom.parseString(SMALL_SAMPLE) saxparser = parser.parser diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 93ca6b99a92..cf40e5a5c85 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -1,7 +1,6 @@ from unittest import mock from test import support from test.support import socket_helper -from test.support import warnings_helper from test.test_httpservers import NoLogRequestHandler from unittest import TestCase from wsgiref.util import setup_testing_defaults @@ -81,41 +80,26 @@ def run_amock(app=hello_app, data=b"GET / HTTP/1.0\n\n"): return out.getvalue(), err.getvalue() -def compare_generic_iter(make_it,match): - """Utility to compare a generic 2.1/2.2+ iterator with an iterable - If running under Python 2.2+, this tests the iterator using iter()/next(), - as well as __getitem__. 'make_it' must be a function returning a fresh +def compare_generic_iter(make_it, match): + """Utility to compare a generic iterator with an iterable + + This tests the iterator using iter()/next(). + 'make_it' must be a function returning a fresh iterator to be tested (since this may test the iterator twice).""" it = make_it() - n = 0 + if not iter(it) is it: + raise AssertionError for item in match: - if not it[n]==item: raise AssertionError - n+=1 + if not next(it) == item: + raise AssertionError try: - it[n] - except IndexError: + next(it) + except StopIteration: pass else: - raise AssertionError("Too many items from __getitem__",it) - - try: - iter, StopIteration - except NameError: - pass - else: - # Only test iter mode under 2.2+ - it = make_it() - if not iter(it) is it: raise AssertionError - for item in match: - if not next(it) == item: raise AssertionError - try: - next(it) - except StopIteration: - pass - else: - raise AssertionError("Too many items from .__next__()", it) + raise AssertionError("Too many items from .__next__()", it) class IntegrationTests(TestCase): @@ -340,7 +324,6 @@ def checkReqURI(self,uri,query=1,**kw): util.setup_testing_defaults(kw) self.assertEqual(util.request_uri(kw,query),uri) - @warnings_helper.ignore_warnings(category=DeprecationWarning) def checkFW(self,text,size,match): def make_it(text=text,size=size): @@ -359,13 +342,6 @@ def make_it(text=text,size=size): it.close() self.assertTrue(it.filelike.closed) - def test_filewrapper_getitem_deprecation(self): - wrapper = util.FileWrapper(StringIO('foobar'), 3) - with self.assertWarnsRegex(DeprecationWarning, - r'Use iterator protocol instead'): - # This should have returned 'bar'. - self.assertEqual(wrapper[1], 'foo') - def testSimpleShifts(self): self.checkShift('','/', '', '/', '') self.checkShift('','/x', 'x', '/x', '') diff --git a/Lib/wsgiref/util.py b/Lib/wsgiref/util.py index cac52eb5a55..cbbe094cba1 100644 --- a/Lib/wsgiref/util.py +++ b/Lib/wsgiref/util.py @@ -17,19 +17,6 @@ def __init__(self, filelike, blksize=8192): if hasattr(filelike,'close'): self.close = filelike.close - def __getitem__(self,key): - import warnings - warnings.warn( - "FileWrapper's __getitem__ method ignores 'key' parameter. " - "Use iterator protocol instead.", - DeprecationWarning, - stacklevel=2 - ) - data = self.filelike.read(self.blksize) - if data: - return data - raise IndexError - def __iter__(self): return self diff --git a/Lib/xml/dom/pulldom.py b/Lib/xml/dom/pulldom.py index 96a8d59519e..913141cd7ef 100644 --- a/Lib/xml/dom/pulldom.py +++ b/Lib/xml/dom/pulldom.py @@ -216,19 +216,6 @@ def reset(self): self.parser.setFeature(xml.sax.handler.feature_namespaces, 1) self.parser.setContentHandler(self.pulldom) - def __getitem__(self, pos): - import warnings - warnings.warn( - "DOMEventStream's __getitem__ method ignores 'pos' parameter. " - "Use iterator protocol instead.", - DeprecationWarning, - stacklevel=2 - ) - rc = self.getEvent() - if rc: - return rc - raise IndexError - def __next__(self): rc = self.getEvent() if rc: diff --git a/Misc/NEWS.d/next/Library/2021-09-07-16-33-51.bpo-45132.WI9zQY.rst b/Misc/NEWS.d/next/Library/2021-09-07-16-33-51.bpo-45132.WI9zQY.rst new file mode 100644 index 00000000000..10f24003dc7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-07-16-33-51.bpo-45132.WI9zQY.rst @@ -0,0 +1,5 @@ +Remove :meth:`__getitem__` methods of +:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` +and :class:`fileinput.FileInput`, deprecated since Python 3.9. + +Patch by Hugo van Kemenade.