Skip to content

bpo-36952: remove bufsize keyword (deprecated 3.6, removed 3.8) #13400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 20, 2019
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
17 changes: 10 additions & 7 deletions Doc/library/fileinput.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ provided by this module.
The following function is the primary interface of this module:


.. function:: input(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None)
.. function:: input(files=None, inplace=False, backup='', *, mode='r', openhook=None)

Create an instance of the :class:`FileInput` class. The instance will be used
as global state for the functions of this module, and is also returned to use
Expand All @@ -72,8 +72,9 @@ The following function is the primary interface of this module:
.. versionchanged:: 3.2
Can be used as a context manager.

.. deprecated-removed:: 3.6 3.8
The *bufsize* parameter.
.. versionchanged:: 3.8
The keyword parameters *mode* and *openhook* are now keyword-only.


The following functions use the global state created by :func:`fileinput.input`;
if there is no active state, :exc:`RuntimeError` is raised.
Expand Down Expand Up @@ -135,7 +136,7 @@ The class which implements the sequence behavior provided by the module is
available for subclassing as well:


.. class:: FileInput(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None)
.. class:: FileInput(files=None, inplace=False, backup='', *, mode='r', openhook=None)

Class :class:`FileInput` is the implementation; its methods :meth:`filename`,
:meth:`fileno`, :meth:`lineno`, :meth:`filelineno`, :meth:`isfirstline`,
Expand All @@ -160,18 +161,20 @@ available for subclassing as well:
with FileInput(files=('spam.txt', 'eggs.txt')) as input:
process(input)


.. versionchanged:: 3.2
Can be used as a context manager.

.. deprecated:: 3.4
The ``'rU'`` and ``'U'`` modes.

.. deprecated-removed:: 3.6 3.8
The *bufsize* parameter.

.. deprecated:: 3.8
Support for :meth:`__getitem__` method is deprecated.

.. versionchanged:: 3.8
The keyword parameter *mode* and *openhook* are now keyword-only.



**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
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,10 @@ The following features and APIs have been removed from Python 3.8:
exposed to the user.
(Contributed by Aviv Palivoda in :issue:`30262`.)

* The ``bufsize`` keyword argument of :func:`fileinput.input` and
:func:`fileinput.FileInput` which was ignored and deprecated since Python 3.6
has been removed. :issue:`36952` (Contributed by Matthias Bussonnier)


Porting to Python 3.8
=====================
Expand Down
13 changes: 4 additions & 9 deletions Lib/fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@

_state = None

def input(files=None, inplace=False, backup="", bufsize=0,
mode="r", openhook=None):
def input(files=None, inplace=False, backup="", *, mode="r", openhook=None):
"""Return an instance of the FileInput class, which can be iterated.

The parameters are passed to the constructor of the FileInput class.
Expand All @@ -91,7 +90,7 @@ def input(files=None, inplace=False, backup="", bufsize=0,
global _state
if _state and _state._file:
raise RuntimeError("input() already active")
_state = FileInput(files, inplace, backup, bufsize, mode, openhook)
_state = FileInput(files, inplace, backup, mode=mode, openhook=openhook)
return _state

def close():
Expand Down Expand Up @@ -173,7 +172,7 @@ def isstdin():
return _state.isstdin()

class FileInput:
"""FileInput([files[, inplace[, backup[, bufsize, [, mode[, openhook]]]]]])
"""FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None)

Class FileInput is the implementation of the module; its methods
filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
Expand All @@ -185,7 +184,7 @@ class FileInput:
sequential order; random access and readline() cannot be mixed.
"""

def __init__(self, files=None, inplace=False, backup="", bufsize=0,
def __init__(self, files=None, inplace=False, backup="", *,
mode="r", openhook=None):
if isinstance(files, str):
files = (files,)
Expand All @@ -201,10 +200,6 @@ def __init__(self, files=None, inplace=False, backup="", bufsize=0,
self._files = files
self._inplace = inplace
self._backup = backup
if bufsize:
import warnings
warnings.warn('bufsize is deprecated and ignored',
DeprecationWarning, stacklevel=2)
self._savestdout = None
self._output = None
self._filename = None
Expand Down
50 changes: 19 additions & 31 deletions Lib/test/test_fileinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,25 +82,17 @@ def close(self):

class BufferSizesTests(BaseTests, unittest.TestCase):
def test_buffer_sizes(self):
# First, run the tests with default and teeny buffer size.
for round, bs in (0, 0), (1, 30):
t1 = self.writeTmp(''.join("Line %s of file 1\n" % (i+1) for i in range(15)))
t2 = self.writeTmp(''.join("Line %s of file 2\n" % (i+1) for i in range(10)))
t3 = self.writeTmp(''.join("Line %s of file 3\n" % (i+1) for i in range(5)))
t4 = self.writeTmp(''.join("Line %s of file 4\n" % (i+1) for i in range(1)))
if bs:
with self.assertWarns(DeprecationWarning):
self.buffer_size_test(t1, t2, t3, t4, bs, round)
else:
self.buffer_size_test(t1, t2, t3, t4, bs, round)

def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):

t1 = self.writeTmp(''.join("Line %s of file 1\n" % (i+1) for i in range(15)))
t2 = self.writeTmp(''.join("Line %s of file 2\n" % (i+1) for i in range(10)))
t3 = self.writeTmp(''.join("Line %s of file 3\n" % (i+1) for i in range(5)))
t4 = self.writeTmp(''.join("Line %s of file 4\n" % (i+1) for i in range(1)))

pat = re.compile(r'LINE (\d+) OF FILE (\d+)')

start = 1 + round*6
if verbose:
print('%s. Simple iteration (bs=%s)' % (start+0, bs))
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
print('1. Simple iteration')
fi = FileInput(files=(t1, t2, t3, t4))
lines = list(fi)
fi.close()
self.assertEqual(len(lines), 31)
Expand All @@ -110,8 +102,8 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):
self.assertEqual(fi.filename(), t4)

if verbose:
print('%s. Status variables (bs=%s)' % (start+1, bs))
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
print('2. Status variables')
fi = FileInput(files=(t1, t2, t3, t4))
s = "x"
while s and s != 'Line 6 of file 2\n':
s = fi.readline()
Expand All @@ -122,15 +114,15 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):
self.assertFalse(fi.isstdin())

if verbose:
print('%s. Nextfile (bs=%s)' % (start+2, bs))
print('3. Nextfile')
fi.nextfile()
self.assertEqual(fi.readline(), 'Line 1 of file 3\n')
self.assertEqual(fi.lineno(), 22)
fi.close()

if verbose:
print('%s. Stdin (bs=%s)' % (start+3, bs))
fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs)
print('4. Stdin')
fi = FileInput(files=(t1, t2, t3, t4, '-'))
savestdin = sys.stdin
try:
sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n")
Expand All @@ -143,27 +135,27 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0):
sys.stdin = savestdin

if verbose:
print('%s. Boundary conditions (bs=%s)' % (start+4, bs))
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
print('5. Boundary conditions')
fi = FileInput(files=(t1, t2, t3, t4))
self.assertEqual(fi.lineno(), 0)
self.assertEqual(fi.filename(), None)
fi.nextfile()
self.assertEqual(fi.lineno(), 0)
self.assertEqual(fi.filename(), None)

if verbose:
print('%s. Inplace (bs=%s)' % (start+5, bs))
print('6. Inplace')
savestdout = sys.stdout
try:
fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs)
fi = FileInput(files=(t1, t2, t3, t4), inplace=1)
for line in fi:
line = line[:-1].upper()
print(line)
fi.close()
finally:
sys.stdout = savestdout

fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
fi = FileInput(files=(t1, t2, t3, t4))
for line in fi:
self.assertEqual(line[-1], '\n')
m = pat.match(line[:-1])
Expand Down Expand Up @@ -533,12 +525,11 @@ def test_pathlib_file_inplace(self):
class MockFileInput:
"""A class that mocks out fileinput.FileInput for use during unit tests"""

def __init__(self, files=None, inplace=False, backup="", bufsize=0,
def __init__(self, files=None, inplace=False, backup="", *,
mode="r", openhook=None):
self.files = files
self.inplace = inplace
self.backup = backup
self.bufsize = bufsize
self.mode = mode
self.openhook = openhook
self._file = None
Expand Down Expand Up @@ -641,13 +632,11 @@ def do_test_call_input(self):
files = object()
inplace = object()
backup = object()
bufsize = object()
mode = object()
openhook = object()

# call fileinput.input() with different values for each argument
result = fileinput.input(files=files, inplace=inplace, backup=backup,
bufsize=bufsize,
mode=mode, openhook=openhook)

# ensure fileinput._state was set to the returned object
Expand All @@ -658,7 +647,6 @@ def do_test_call_input(self):
self.assertIs(files, result.files, "files")
self.assertIs(inplace, result.inplace, "inplace")
self.assertIs(backup, result.backup, "backup")
self.assertIs(bufsize, result.bufsize, "bufsize")
self.assertIs(mode, result.mode, "mode")
self.assertIs(openhook, result.openhook, "openhook")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:func:`fileinput.input` and :class:`fileinput.FileInput` **bufsize**
argument has been removed (was deprecated and ignored since Python 3.6),
and as a result the **mode** and **openhook** arguments have been made
keyword-only.