Commit 4eb5f1a5 authored by Georg Brandl's avatar Georg Brandl

merge with main repo 3.2 branch

parents a7d2f006 5be6d74a
...@@ -284,7 +284,7 @@ are able to handle the less common cases not covered by the convenience ...@@ -284,7 +284,7 @@ are able to handle the less common cases not covered by the convenience
functions. functions.
.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, \ .. class:: Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, \
stderr=None, preexec_fn=None, close_fds=True, shell=False, \ stderr=None, preexec_fn=None, close_fds=True, shell=False, \
cwd=None, env=None, universal_newlines=False, \ cwd=None, env=None, universal_newlines=False, \
startupinfo=None, creationflags=0, restore_signals=True, \ startupinfo=None, creationflags=0, restore_signals=True, \
...@@ -356,17 +356,20 @@ functions. ...@@ -356,17 +356,20 @@ functions.
untrusted input. See the warning under :ref:`frequently-used-arguments` untrusted input. See the warning under :ref:`frequently-used-arguments`
for details. for details.
*bufsize*, if given, has the same meaning as the corresponding argument to the *bufsize* will be supplied as the corresponding argument to the :meth:`io.open`
built-in open() function: :const:`0` means unbuffered, :const:`1` means line function when creating the stdin/stdout/stderr pipe file objects:
buffered, any other positive value means use a buffer of (approximately) that :const:`0` means unbuffered (read and write are one system call and can return short),
size. A negative *bufsize* means to use the system default, which usually means :const:`1` means line buffered, any other positive value means use a buffer of
fully buffered. The default value for *bufsize* is :const:`0` (unbuffered). approximately that size. A negative bufsize (the default) means
the system default of io.DEFAULT_BUFFER_SIZE will be used.
.. note:: .. versionchanged:: 3.2.4
If you experience performance issues, it is recommended that you try to *bufsize* now defaults to -1 to enable buffering by default to match the
enable buffering by setting *bufsize* to either -1 or a large enough behavior that most code expects. In 3.2.0 through 3.2.3 it incorrectly
positive value (such as 4096). defaulted to :const:`0` which was unbuffered and allowed short reads.
This was unintentional and did not match the behavior of Python 2 as
most code expected.
The *executable* argument specifies a replacement program to execute. It The *executable* argument specifies a replacement program to execute. It
is very seldom needed. When ``shell=False``, *executable* replaces the is very seldom needed. When ``shell=False``, *executable* replaces the
......
...@@ -25,7 +25,7 @@ Using the subprocess module ...@@ -25,7 +25,7 @@ Using the subprocess module
=========================== ===========================
This module defines one class called Popen: This module defines one class called Popen:
class Popen(args, bufsize=0, executable=None, class Popen(args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, preexec_fn=None, close_fds=True, shell=False,
cwd=None, env=None, universal_newlines=False, cwd=None, env=None, universal_newlines=False,
...@@ -56,12 +56,12 @@ not all MS Windows applications interpret the command line the same ...@@ -56,12 +56,12 @@ not all MS Windows applications interpret the command line the same
way: The list2cmdline is designed for applications using the same way: The list2cmdline is designed for applications using the same
rules as the MS C runtime. rules as the MS C runtime.
bufsize, if given, has the same meaning as the corresponding argument bufsize will be supplied as the corresponding argument to the io.open()
to the built-in open() function: 0 means unbuffered, 1 means line function when creating the stdin/stdout/stderr pipe file objects:
buffered, any other positive value means use a buffer of 0 means unbuffered (read & write are one system call and can return short),
(approximately) that size. A negative bufsize means to use the system 1 means line buffered, any other positive value means use a buffer of
default, which usually means fully buffered. The default value for approximately that size. A negative bufsize, the default, means the system
bufsize is 0 (unbuffered). default of io.DEFAULT_BUFFER_SIZE will be used.
stdin, stdout and stderr specify the executed programs' standard stdin, stdout and stderr specify the executed programs' standard
input, standard output and standard error file handles, respectively. input, standard output and standard error file handles, respectively.
...@@ -638,7 +638,7 @@ _PLATFORM_DEFAULT_CLOSE_FDS = object() ...@@ -638,7 +638,7 @@ _PLATFORM_DEFAULT_CLOSE_FDS = object()
class Popen(object): class Popen(object):
def __init__(self, args, bufsize=0, executable=None, def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS, preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False, shell=False, cwd=None, env=None, universal_newlines=False,
...@@ -650,7 +650,7 @@ class Popen(object): ...@@ -650,7 +650,7 @@ class Popen(object):
self._child_created = False self._child_created = False
if bufsize is None: if bufsize is None:
bufsize = 0 # Restore default bufsize = -1 # Restore default
if not isinstance(bufsize, int): if not isinstance(bufsize, int):
raise TypeError("bufsize must be an integer") raise TypeError("bufsize must be an integer")
......
...@@ -46,6 +46,9 @@ class _TriggerThread(threading.Thread): ...@@ -46,6 +46,9 @@ class _TriggerThread(threading.Thread):
class BlockingTestMixin: class BlockingTestMixin:
def tearDown(self):
self.t = None
def do_blocking_test(self, block_func, block_args, trigger_func, trigger_args): def do_blocking_test(self, block_func, block_args, trigger_func, trigger_args):
self.t = _TriggerThread(trigger_func, trigger_args) self.t = _TriggerThread(trigger_func, trigger_args)
self.t.start() self.t.start()
...@@ -260,7 +263,7 @@ class FailingQueue(queue.Queue): ...@@ -260,7 +263,7 @@ class FailingQueue(queue.Queue):
raise FailingQueueException("You Lose") raise FailingQueueException("You Lose")
return queue.Queue._get(self) return queue.Queue._get(self)
class FailingQueueTest(unittest.TestCase, BlockingTestMixin): class FailingQueueTest(BlockingTestMixin, unittest.TestCase):
def failing_queue_test(self, q): def failing_queue_test(self, q):
if q.qsize(): if q.qsize():
......
...@@ -79,6 +79,28 @@ class PopenExecuteChildRaises(subprocess.Popen): ...@@ -79,6 +79,28 @@ class PopenExecuteChildRaises(subprocess.Popen):
class ProcessTestCase(BaseTestCase): class ProcessTestCase(BaseTestCase):
def test_io_buffered_by_default(self):
p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
try:
self.assertIsInstance(p.stdin, io.BufferedIOBase)
self.assertIsInstance(p.stdout, io.BufferedIOBase)
self.assertIsInstance(p.stderr, io.BufferedIOBase)
finally:
p.wait()
def test_io_unbuffered_works(self):
p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, bufsize=0)
try:
self.assertIsInstance(p.stdin, io.RawIOBase)
self.assertIsInstance(p.stdout, io.RawIOBase)
self.assertIsInstance(p.stderr, io.RawIOBase)
finally:
p.wait()
def test_call_seq(self): def test_call_seq(self):
# call() function with sequence argument # call() function with sequence argument
rc = subprocess.call([sys.executable, "-c", rc = subprocess.call([sys.executable, "-c",
......
...@@ -233,6 +233,11 @@ Core and Builtins ...@@ -233,6 +233,11 @@ Core and Builtins
Library Library
------- -------
- Issue #17488: Change the subprocess.Popen bufsize parameter default value
from unbuffered (0) to buffering (-1) to match the behavior existing code
expects and match the behavior of the subprocess module in Python 2 to avoid
introducing hard to track down bugs.
- Issue #17521: Corrected non-enabling of logger following two calls to - Issue #17521: Corrected non-enabling of logger following two calls to
fileConfig(). fileConfig().
...@@ -1079,6 +1084,8 @@ Tests ...@@ -1079,6 +1084,8 @@ Tests
Build Build
----- -----
- Issue #17425: Build with openssl 1.0.0k on Windows.
- Issue #16754: Fix the incorrect shared library extension on linux. Introduce - Issue #16754: Fix the incorrect shared library extension on linux. Introduce
two makefile macros SHLIB_SUFFIX and EXT_SUFFIX. SO now has the value of two makefile macros SHLIB_SUFFIX and EXT_SUFFIX. SO now has the value of
SHLIB_SUFFIX again (as in 2.x and 3.1). The SO macro is removed in 3.4. SHLIB_SUFFIX again (as in 2.x and 3.1). The SO macro is removed in 3.4.
......
...@@ -153,9 +153,9 @@ _ssl ...@@ -153,9 +153,9 @@ _ssl
Unpack into the "dist" directory, retaining the folder name from Unpack into the "dist" directory, retaining the folder name from
the archive - for example, the latest stable OpenSSL will install as the archive - for example, the latest stable OpenSSL will install as
dist/openssl-1.0.0j dist/openssl-1.0.0k
You need to use version 1.0.0j of OpenSSL. You need to use version 1.0.0k of OpenSSL.
You can install the NASM assembler from You can install the NASM assembler from
http://www.nasm.us/ http://www.nasm.us/
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
/> />
<UserMacro <UserMacro
Name="opensslDir" Name="opensslDir"
Value="$(externalsDir)\openssl-1.0.0j" Value="$(externalsDir)\openssl-1.0.0k"
/> />
<UserMacro <UserMacro
Name="tcltkDir" Name="tcltkDir"
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
/> />
<UserMacro <UserMacro
Name="opensslDir" Name="opensslDir"
Value="$(externalsDir)\openssl-1.0.0j" Value="$(externalsDir)\openssl-1.0.0k"
/> />
<UserMacro <UserMacro
Name="tcltkDir" Name="tcltkDir"
......
...@@ -139,7 +139,7 @@ _ssl ...@@ -139,7 +139,7 @@ _ssl
Get the source code through Get the source code through
svn export http://svn.python.org/projects/external/openssl-1.0.0j svn export http://svn.python.org/projects/external/openssl-1.0.0k
** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for ** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for
obtaining external sources then you don't need to manually get the source obtaining external sources then you don't need to manually get the source
......
...@@ -14,7 +14,7 @@ cd .. ...@@ -14,7 +14,7 @@ cd ..
@rem if exist tk8.4.16 rd /s/q tk8.4.16 @rem if exist tk8.4.16 rd /s/q tk8.4.16
@rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1 @rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1
@rem if exist db-4.4.20 rd /s/q db-4.4.20 @rem if exist db-4.4.20 rd /s/q db-4.4.20
@rem if exist openssl-1.0.0j rd /s/q openssl-1.0.0j @rem if exist openssl-1.0.0k rd /s/q openssl-1.0.0k
@rem if exist sqlite-3.7.4 rd /s/q sqlite-3.7.4 @rem if exist sqlite-3.7.4 rd /s/q sqlite-3.7.4
@rem bzip @rem bzip
...@@ -24,7 +24,7 @@ if not exist bzip2-1.0.6 ( ...@@ -24,7 +24,7 @@ if not exist bzip2-1.0.6 (
) )
@rem OpenSSL @rem OpenSSL
if not exist openssl-1.0.0j svn export http://svn.python.org/projects/external/openssl-1.0.0j if not exist openssl-1.0.0k svn export http://svn.python.org/projects/external/openssl-1.0.0k
@rem tcl/tk @rem tcl/tk
if not exist tcl-8.5.9.0 ( if not exist tcl-8.5.9.0 (
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment