From 84a13fbda0d79789e3c9efcc9f64752261ce1e8d Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 11 Aug 2018 09:05:04 +0300 Subject: [PATCH] bpo-9372: Deprecate several __getitem__ methods (GH-8609) The __getitem__ methods of DOMEventStream, FileInput, and FileWrapper classes ignore their 'index' parameters and return the next item instead. --- Doc/library/fileinput.rst | 3 +++ Doc/library/wsgiref.rst | 2 ++ Doc/library/xml.dom.pulldom.rst | 2 ++ Doc/whatsnew/3.8.rst | 9 +++++++++ Lib/fileinput.py | 7 +++++++ Lib/test/support/__init__.py | 17 +++++++++++++++++ Lib/test/test_fileinput.py | 10 ++++++++++ Lib/test/test_pulldom.py | 7 +++++++ Lib/test/test_wsgiref.py | 8 ++++++++ Lib/wsgiref/util.py | 7 +++++++ Lib/xml/dom/pulldom.py | 7 +++++++ .../2018-08-01-21-26-17.bpo-9372.V8Ou3K.rst | 3 +++ 12 files changed, 82 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-08-01-21-26-17.bpo-9372.V8Ou3K.rst diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 5881fefe29..f1e29a8a7d 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -169,6 +169,9 @@ available for subclassing as well: .. deprecated-removed:: 3.6 3.8 The *bufsize* parameter. + .. deprecated:: 3.8 + Support for :meth:`__getitem__` method is deprecated. + **Optional in-place filtering:** if the keyword argument ``inplace=True`` is passed to :func:`fileinput.input` or to the :class:`FileInput` constructor, the diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 2d9b7b359e..f8811c5a36 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -173,6 +173,8 @@ also provides these miscellaneous utilities: for chunk in wrapper: print(chunk) + .. deprecated:: 3.8 + Support for :meth:`sequence protocol <__getitem__>` is deprecated. :mod:`wsgiref.headers` -- WSGI response header tools diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index 5c0f469ad7..56f545c0e6 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -100,6 +100,8 @@ DOMEventStream Objects .. class:: DOMEventStream(stream, parser, bufsize) + .. deprecated:: 3.8 + Support for :meth:`sequence protocol <__getitem__>` is deprecated. .. method:: getEvent() diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 6e0c8b807c..ef5455a9f6 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -154,6 +154,15 @@ Build and C API Changes (Contributed by Antoine Pitrou in :issue:`32430`.) +* The :meth:`__getitem__` methods of :class:`xml.dom.pulldom.DOMEventStream`, + :class:`wsgiref.util.FileWrapper` and :class:`fileinput.FileInput` have been + deprecated. + + Implementations of these methods have been ignoring their *index* parameter, + and returning the next item instead. + + (Contributed by Berker Peksag in :issue:`9372`.) + Deprecated ========== diff --git a/Lib/fileinput.py b/Lib/fileinput.py index c6fc9a1981..a7f8df37aa 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -259,6 +259,13 @@ class FileInput: # 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: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d8dabd4358..13b60f7e81 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -89,6 +89,7 @@ __all__ = [ "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_unless_bind_unix_socket", + "ignore_warnings", # sys "is_jython", "is_android", "check_impl_detail", "unix_shell", "setswitchinterval", @@ -138,6 +139,22 @@ def _ignore_deprecated_imports(ignore=True): yield +def ignore_warnings(*, category): + """Decorator to suppress deprecation warnings. + + Use of context managers to hide warnings make diffs + more noisy and tools like 'git blame' less useful. + """ + def decorator(test): + @functools.wraps(test) + def wrapper(self, *args, **kwargs): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=category) + return test(self, *args, **kwargs) + return wrapper + return decorator + + def import_module(name, deprecated=False, *, required_on=()): """Import and return the module to be tested, raising SkipTest if it is not available. diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index c97bb4cb3b..c5d722e58f 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -351,6 +351,7 @@ class FileInputTests(BaseTests, unittest.TestCase): with FileInput(files=[]) as fi: self.assertEqual(fi._files, ('-',)) + @support.ignore_warnings(category=DeprecationWarning) def test__getitem__(self): """Tests invoking FileInput.__getitem__() with the current line number""" @@ -361,6 +362,14 @@ class FileInputTests(BaseTests, unittest.TestCase): 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") + + @support.ignore_warnings(category=DeprecationWarning) def test__getitem__invalid_key(self): """Tests invoking FileInput.__getitem__() with an index unequal to the line number""" @@ -370,6 +379,7 @@ class FileInputTests(BaseTests, unittest.TestCase): fi[1] self.assertEqual(cm.exception.args, ("accessing lines out of order",)) + @support.ignore_warnings(category=DeprecationWarning) def test__getitem__eof(self): """Tests invoking FileInput.__getitem__() with the line number but at end-of-input""" diff --git a/Lib/test/test_pulldom.py b/Lib/test/test_pulldom.py index 3d89e3adda..f454098c65 100644 --- a/Lib/test/test_pulldom.py +++ b/Lib/test/test_pulldom.py @@ -159,6 +159,13 @@ class PullDOMTestCase(unittest.TestCase): 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) + class ThoroughTestCase(unittest.TestCase): """Test the hard-to-reach parts of pulldom.""" diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 8422b308d7..737dfed3a5 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -338,6 +338,7 @@ class UtilityTests(TestCase): util.setup_testing_defaults(kw) self.assertEqual(util.request_uri(kw,query),uri) + @support.ignore_warnings(category=DeprecationWarning) def checkFW(self,text,size,match): def make_it(text=text,size=size): @@ -356,6 +357,13 @@ class UtilityTests(TestCase): 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 516fe898d0..1cff7a3745 100644 --- a/Lib/wsgiref/util.py +++ b/Lib/wsgiref/util.py @@ -18,6 +18,13 @@ class FileWrapper: 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 diff --git a/Lib/xml/dom/pulldom.py b/Lib/xml/dom/pulldom.py index 43504f7656..96a8d59519 100644 --- a/Lib/xml/dom/pulldom.py +++ b/Lib/xml/dom/pulldom.py @@ -217,6 +217,13 @@ class DOMEventStream: 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 diff --git a/Misc/NEWS.d/next/Library/2018-08-01-21-26-17.bpo-9372.V8Ou3K.rst b/Misc/NEWS.d/next/Library/2018-08-01-21-26-17.bpo-9372.V8Ou3K.rst new file mode 100644 index 0000000000..8ae5ce118f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-08-01-21-26-17.bpo-9372.V8Ou3K.rst @@ -0,0 +1,3 @@ +Deprecate :meth:`__getitem__` methods of +:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` +and :class:`fileinput.FileInput`. -- 2.40.0