Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/library/fileinput.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Doc/library/wsgiref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Doc/library/xml.dom.pulldom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ DOMEventStream Objects

.. class:: DOMEventStream(stream, parser, bufsize)

.. deprecated:: 3.8
Support for :meth:`sequence protocol <__getitem__>` is deprecated.

.. method:: getEvent()

Expand Down
9 changes: 9 additions & 0 deletions Doc/whatsnew/3.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
==========
Expand Down
7 changes: 7 additions & 0 deletions Lib/fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ def __next__(self):
# 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:
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"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",
Expand Down Expand Up @@ -138,6 +139,22 @@ def _ignore_deprecated_imports(ignore=True):
yield


def ignore_warnings(*, category):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it is a keyword-only parameter? For a single argument I expect a positional parameter.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many warning-related APIs both in the stdlib and test.support and it's easy to forget how to use them, so I just tried to make the API more strict, easy to remember, and avoid misusing of the function.

"""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.
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ def test_empty_files_list_specified_to_constructor(self):
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"""
Expand All @@ -361,6 +362,14 @@ def test__getitem__(self):
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"""
Expand All @@ -370,6 +379,7 @@ def test__getitem__invalid_key(self):
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"""
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_pulldom.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ 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)


class ThoroughTestCase(unittest.TestCase):
"""Test the hard-to-reach parts of pulldom."""
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_wsgiref.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ def checkReqURI(self,uri,query=1,**kw):
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):
Expand All @@ -356,6 +357,13 @@ 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', '')
Expand Down
7 changes: 7 additions & 0 deletions Lib/wsgiref/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ def __init__(self, filelike, blksize=8192):
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
Expand Down
7 changes: 7 additions & 0 deletions Lib/xml/dom/pulldom.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@ def reset(self):
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Deprecate :meth:`__getitem__` methods of
:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper`
and :class:`fileinput.FileInput`.