summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/howto/urllib2.rst29
-rw-r--r--Doc/library/dummy_threading.rst2
-rw-r--r--Doc/library/functions.rst3
-rw-r--r--Doc/library/os.rst19
-rw-r--r--Doc/library/subprocess.rst65
-rw-r--r--Doc/library/tempfile.rst3
-rw-r--r--Lib/logging/handlers.py10
-rw-r--r--Lib/pstats.py6
-rw-r--r--Lib/subprocess.py14
-rw-r--r--Lib/test/test_subprocess.py47
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS13
-rw-r--r--Modules/_posixsubprocess.c7
-rw-r--r--Objects/longobject.c19
-rw-r--r--Objects/rangeobject.c3
-rw-r--r--Objects/sliceobject.c3
-rw-r--r--Objects/unicodeobject.c3
17 files changed, 164 insertions, 83 deletions
diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst
index fade4a3..87f42ba 100644
--- a/Doc/howto/urllib2.rst
+++ b/Doc/howto/urllib2.rst
@@ -137,7 +137,7 @@ This is done as follows::
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.parse.urlencode(data)
- >>> print(url_values)
+ >>> print(url_values) # The order may differ from below. #doctest: +SKIP
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
@@ -207,9 +207,9 @@ e.g. ::
>>> req = urllib.request.Request('http://www.pretend_server.org')
>>> try: urllib.request.urlopen(req)
- >>> except urllib.error.URLError as e:
- >>> print(e.reason)
- >>>
+ ... except urllib.error.URLError as e:
+ ... print(e.reason) #doctest: +SKIP
+ ...
(4, 'getaddrinfo failed')
@@ -315,18 +315,17 @@ geturl, and info, methods as returned by the ``urllib.response`` module::
>>> req = urllib.request.Request('http://www.python.org/fish.html')
>>> try:
- >>> urllib.request.urlopen(req)
- >>> except urllib.error.HTTPError as e:
- >>> print(e.code)
- >>> print(e.read())
- >>>
+ ... urllib.request.urlopen(req)
+ ... except urllib.error.HTTPError as e:
+ ... print(e.code)
+ ... print(e.read()) #doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
+ ...
404
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
- <?xml-stylesheet href="./css/ht2html.css"
- type="text/css"?>
- <html><head><title>Error 404: File Not Found</title>
- ...... etc...
+ b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
+ ...
+ <title>Page Not Found</title>\n
+ ...
Wrapping it Up
--------------
diff --git a/Doc/library/dummy_threading.rst b/Doc/library/dummy_threading.rst
index b578324..30a3ebb 100644
--- a/Doc/library/dummy_threading.rst
+++ b/Doc/library/dummy_threading.rst
@@ -17,7 +17,7 @@ Suggested usage is::
try:
import threading
except ImportError:
- import dummy_threading
+ import dummy_threading as threading
Be careful to not use this module where deadlock might occur from a thread being
created that blocks waiting for another thread to be created. This often occurs
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 1ee8540..2575d7f 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -1236,7 +1236,8 @@ are always available. They are listed here in alphabetical order.
standard type hierarchy in :ref:`types`.
-.. function:: str([object[, encoding[, errors]]])
+.. function:: str(object='')
+ str(object[, encoding[, errors]])
Return a string version of an object, using one of the following modes:
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 5991e29..410e03a 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1183,18 +1183,21 @@ Files and Directories
single: UNC paths; and os.makedirs()
Recursive directory creation function. Like :func:`mkdir`, but makes all
- intermediate-level directories needed to contain the leaf directory. If
- the target directory with the same mode as specified already exists,
- raises an :exc:`OSError` exception if *exist_ok* is False, otherwise no
- exception is raised. If the directory cannot be created in other cases,
- raises an :exc:`OSError` exception. The default *mode* is ``0o777`` (octal).
- On some systems, *mode* is ignored. Where it is used, the current umask
- value is first masked out.
+ intermediate-level directories needed to contain the leaf directory.
+
+ The default *mode* is ``0o777`` (octal). On some systems, *mode* is
+ ignored. Where it is used, the current umask value is first masked out.
+
+ If *exists_ok* is ``False`` (the default), an :exc:`OSError` is raised if
+ the target directory already exists. If *exists_ok* is ``True`` an
+ :exc:`OSError` is still raised if the umask-masked *mode* is different from
+ the existing mode, on systems where the mode is used. :exc:`OSError` will
+ also be raised if the directory creation fails.
.. note::
:func:`makedirs` will become confused if the path elements to create
- include :data:`pardir`.
+ include :data:`pardir` (eg. ".." on UNIX systems).
This function handles UNC paths correctly.
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index e4c1ad4..268f0b8 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -290,20 +290,15 @@ functions.
Arguments are:
- *args* should be a string, or a sequence of program arguments. The program
- to execute is normally the first item in the args sequence or the string if
- a string is given, but can be explicitly set by using the *executable*
- argument. When *executable* is given, the first item in the args sequence
- is still treated by most programs as the command name, which can then be
- different from the actual executable name. On Unix, it becomes the display
- name for the executing program in utilities such as :program:`ps`.
-
- On Unix, with *shell=False* (default): In this case, the Popen class uses
- :meth:`os.execvp` like behavior to execute the child program.
- *args* should normally be a
- sequence. If a string is specified for *args*, it will be used as the name
- or path of the program to execute; this will only work if the program is
- being given no arguments.
+ *args* should be a sequence of program arguments or else a single string.
+ By default, the program to execute is the first item in *args* if *args* is
+ a sequence and the string itself if *args* is a string. However, see the
+ *shell* and *executable* arguments for differences from this behavior.
+
+ On Unix, the :class:`Popen` class uses :meth:`os.execvp`-like behavior to
+ execute the child program. If *args* is a string, the string is
+ interpreted as the name or path of the program to execute; this only works
+ if the program is being given no arguments.
.. note::
@@ -324,13 +319,23 @@ functions.
used in the shell (such as filenames containing spaces or the *echo* command
shown above) are single list elements.
- On Unix, with *shell=True*: If args is a string, it specifies the command
- string to execute through the shell. This means that the string must be
+ On Windows, the :class:`Popen` class uses ``CreateProcess()`` to
+ execute the child program, which operates on strings. If *args* is a
+ sequence, it will be converted to a string in a manner described in
+ :ref:`converting-argument-sequence`.
+
+ The *shell* argument (which defaults to *False*) specifies whether to use
+ the shell as the program to execute. It is recommended to pass *args* as a
+ sequence if *shell* is *False* and as a string if *shell* is *True*.
+
+ On Unix with ``shell=True``, the shell defaults to :file:`/bin/sh`. If
+ *args* is a string, the string specifies the command
+ to execute through the shell. This means that the string must be
formatted exactly as it would be when typed at the shell prompt. This
includes, for example, quoting or backslash escaping filenames with spaces in
them. If *args* is a sequence, the first item specifies the command string, and
any additional items will be treated as additional arguments to the shell
- itself. That is to say, *Popen* does the equivalent of::
+ itself. That is to say, :class:`Popen` does the equivalent of::
Popen(['/bin/sh', '-c', args[0], args[1], ...])
@@ -340,10 +345,11 @@ functions.
input. See the warning under :ref:`frequently-used-arguments`
for details.
- On Windows: the :class:`Popen` class uses CreateProcess() to execute the
- child program, which operates on strings. If *args* is a sequence, it will
- be converted to a string in a manner described in
- :ref:`converting-argument-sequence`.
+ On Windows with ``shell=True``, the :envvar:`COMSPEC` environment variable
+ specifies the default shell. The only time you need to specify
+ ``shell=True`` on Windows is when the command you wish to execute is built
+ into the shell (e.g. :command:`dir` or :command:`copy`). You do not need
+ ``shell=True`` to run a batch file or console-based executable.
*bufsize*, if given, has the same meaning as the corresponding argument to the
built-in open() function: :const:`0` means unbuffered, :const:`1` means line
@@ -357,15 +363,14 @@ functions.
enable buffering by setting *bufsize* to either -1 or a large enough
positive value (such as 4096).
- The *executable* argument specifies the program to execute. It is very seldom
- needed: Usually, the program to execute is defined by the *args* argument. If
- ``shell=True``, the *executable* argument specifies which shell to use. On Unix,
- the default shell is :file:`/bin/sh`. On Windows, the default shell is
- specified by the :envvar:`COMSPEC` environment variable. The only reason you
- would need to specify ``shell=True`` on Windows is where the command you
- wish to execute is actually built in to the shell, eg ``dir``, ``copy``.
- You don't need ``shell=True`` to run a batch file, nor to run a console-based
- executable.
+ The *executable* argument specifies a replacement program to execute. It
+ is very seldom needed. When ``shell=False``, *executable* replaces the
+ program to execute specified by *args*. However, the *args* program is
+ still treated by most programs as the command name, which can then be
+ different from the program actually executed. On Unix, the *args* name
+ becomes the display name for the executable in utilities such as
+ :program:`ps`. If ``shell=True``, on Unix the *executable* argument
+ specifies a replacement shell for the default :file:`/bin/sh`.
*stdin*, *stdout* and *stderr* specify the executed program's standard input,
standard output and standard error file handles, respectively. Valid values
diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst
index fff6c4e..c143b88 100644
--- a/Doc/library/tempfile.rst
+++ b/Doc/library/tempfile.rst
@@ -76,7 +76,8 @@ The module defines the following user-callable items:
data is spooled in memory until the file size exceeds *max_size*, or
until the file's :func:`fileno` method is called, at which point the
contents are written to disk and operation proceeds as with
- :func:`TemporaryFile`.
+ :func:`TemporaryFile`. Also, it's ``truncate`` method does not
+ accept a ``size`` argument.
The resulting file has one additional method, :func:`rollover`, which
causes the file to roll over to an on-disk file regardless of its size.
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index d4df5c6..2e29f92 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -754,18 +754,12 @@ class SysLogHandler(logging.Handler):
self.formatter = None
def _connect_unixsocket(self, address):
- self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
- # syslog may require either DGRAM or STREAM sockets
+ self.socket = socket.socket(socket.AF_UNIX, self.socktype)
try:
self.socket.connect(address)
except socket.error:
self.socket.close()
- self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- self.socket.connect(address)
- except socket.error:
- self.socket.close()
- raise
+ raise
def encodePriority(self, facility, priority):
"""
diff --git a/Lib/pstats.py b/Lib/pstats.py
index 3f0add2..bfbaa41 100644
--- a/Lib/pstats.py
+++ b/Lib/pstats.py
@@ -159,15 +159,19 @@ class Stats:
# along with some printable description
sort_arg_dict_default = {
"calls" : (((1,-1), ), "call count"),
+ "ncalls" : (((1,-1), ), "call count"),
+ "cumtime" : (((3,-1), ), "cumulative time"),
"cumulative": (((3,-1), ), "cumulative time"),
"file" : (((4, 1), ), "file name"),
+ "filename" : (((4, 1), ), "file name"),
"line" : (((5, 1), ), "line number"),
"module" : (((4, 1), ), "file name"),
"name" : (((6, 1), ), "function name"),
"nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"),
- "pcalls" : (((0,-1), ), "call count"),
+ "pcalls" : (((0,-1), ), "primitive call count"),
"stdname" : (((7, 1), ), "standard name"),
"time" : (((2,-1), ), "internal time"),
+ "tottime" : (((2,-1), ), "internal time"),
}
def get_sort_arg_defs(self):
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 93262df..83c79ef 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1169,6 +1169,7 @@ class Popen(object):
if executable is None:
executable = args[0]
+ orig_executable = executable
# For transferring possible exec failure from child to parent.
# Data format: "exception name:hex errno:description"
@@ -1224,6 +1225,7 @@ class Popen(object):
self._child_created = True
if self.pid == 0:
# Child
+ reached_preexec = False
try:
# Close parent's pipe ends
if p2cwrite != -1:
@@ -1288,6 +1290,7 @@ class Popen(object):
if start_new_session and hasattr(os, 'setsid'):
os.setsid()
+ reached_preexec = True
if preexec_fn:
preexec_fn()
@@ -1303,6 +1306,8 @@ class Popen(object):
errno_num = exc_value.errno
else:
errno_num = 0
+ if not reached_preexec:
+ exc_value = "noexec"
message = '%s:%x:%s' % (exc_type.__name__,
errno_num, exc_value)
message = message.encode(errors="surrogatepass")
@@ -1364,10 +1369,17 @@ class Popen(object):
err_msg = err_msg.decode(errors="surrogatepass")
if issubclass(child_exception_type, OSError) and hex_errno:
errno_num = int(hex_errno, 16)
+ child_exec_never_called = (err_msg == "noexec")
+ if child_exec_never_called:
+ err_msg = ""
if errno_num != 0:
err_msg = os.strerror(errno_num)
if errno_num == errno.ENOENT:
- err_msg += ': ' + repr(args[0])
+ if child_exec_never_called:
+ # The error must be from chdir(cwd).
+ err_msg += ': ' + repr(cwd)
+ else:
+ err_msg += ': ' + repr(orig_executable)
raise child_exception_type(errno_num, err_msg)
raise child_exception_type(err_msg)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 2879641..15fb498 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -884,24 +884,30 @@ class _SuppressCoreFiles(object):
@unittest.skipIf(mswindows, "POSIX specific tests")
class POSIXProcessTestCase(BaseTestCase):
- def test_exceptions(self):
- nonexistent_dir = "/_this/pa.th/does/not/exist"
+ def setUp(self):
+ super().setUp()
+ self._nonexistent_dir = "/_this/pa.th/does/not/exist"
+
+ def _get_chdir_exception(self):
try:
- os.chdir(nonexistent_dir)
+ os.chdir(self._nonexistent_dir)
except OSError as e:
# This avoids hard coding the errno value or the OS perror()
# string and instead capture the exception that we want to see
# below for comparison.
desired_exception = e
- desired_exception.strerror += ': ' + repr(sys.executable)
+ desired_exception.strerror += ': ' + repr(self._nonexistent_dir)
else:
self.fail("chdir to nonexistant directory %s succeeded." %
- nonexistent_dir)
+ self._nonexistent_dir)
+ return desired_exception
- # Error in the child re-raised in the parent.
+ def test_exception_cwd(self):
+ """Test error in the child raised in the parent for a bad cwd."""
+ desired_exception = self._get_chdir_exception()
try:
p = subprocess.Popen([sys.executable, "-c", ""],
- cwd=nonexistent_dir)
+ cwd=self._nonexistent_dir)
except OSError as e:
# Test that the child process chdir failure actually makes
# it up to the parent process as the correct exception.
@@ -910,6 +916,33 @@ class POSIXProcessTestCase(BaseTestCase):
else:
self.fail("Expected OSError: %s" % desired_exception)
+ def test_exception_bad_executable(self):
+ """Test error in the child raised in the parent for a bad executable."""
+ desired_exception = self._get_chdir_exception()
+ try:
+ p = subprocess.Popen([sys.executable, "-c", ""],
+ executable=self._nonexistent_dir)
+ except OSError as e:
+ # Test that the child process exec failure actually makes
+ # it up to the parent process as the correct exception.
+ self.assertEqual(desired_exception.errno, e.errno)
+ self.assertEqual(desired_exception.strerror, e.strerror)
+ else:
+ self.fail("Expected OSError: %s" % desired_exception)
+
+ def test_exception_bad_args_0(self):
+ """Test error in the child raised in the parent for a bad args[0]."""
+ desired_exception = self._get_chdir_exception()
+ try:
+ p = subprocess.Popen([self._nonexistent_dir, "-c", ""])
+ except OSError as e:
+ # Test that the child process exec failure actually makes
+ # it up to the parent process as the correct exception.
+ self.assertEqual(desired_exception.errno, e.errno)
+ self.assertEqual(desired_exception.strerror, e.strerror)
+ else:
+ self.fail("Expected OSError: %s" % desired_exception)
+
def test_restore_signals(self):
# Code coverage for both values of restore_signals to make sure it
# at least does not blow up.
diff --git a/Misc/ACKS b/Misc/ACKS
index ca7431b..7429f77 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -47,6 +47,7 @@ Chris AtLee
John Aycock
Jan-Hein Bührman
Donovan Baarda
+Arne Babenhauserheide
Attila Babo
Alfonso Baciero
Marcin Bachry
diff --git a/Misc/NEWS b/Misc/NEWS
index bc5470a..9e1e96b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.2.4
Core and Builtins
-----------------
+- Issue #14783: Improve int() docstring and switch docstrings for str(),
+ range(), and slice() to use multi-line signatures.
+
- Issue #15379: Fix passing of non-BMP characters as integers for the charmap
decoder (already working as unicode strings). Patch by Serhiy Storchaka.
@@ -126,6 +129,10 @@ Core and Builtins
Library
-------
+- Issue #16114: The subprocess module no longer provides a misleading
+ error message stating that args[0] did not exist when either the cwd or
+ executable keyword arguments specified a path that did not exist.
+
- Issue #15756: subprocess.poll() now properly handles errno.ECHILD to
return a returncode of 0 when the child has already exited or cannot
be waited on.
@@ -606,6 +613,12 @@ Build
Documentation
-------------
+- Issue #16115: Improve subprocess.Popen() documentation around args, shell,
+ and executable arguments.
+
+- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with
+ great native-speaker help from R. David Murray.
+
- Issue #15533: Clarify docs and add tests for subprocess.Popen()'s cwd
argument.
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 59673f4..19ca31f 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -354,7 +354,7 @@ child_exec(char *const exec_array[],
PyObject *preexec_fn,
PyObject *preexec_fn_args_tuple)
{
- int i, saved_errno, unused;
+ int i, saved_errno, unused, reached_preexec = 0;
PyObject *result;
const char* err_msg = "";
/* Buffer large enough to hold a hex integer. We can't malloc. */
@@ -438,6 +438,7 @@ child_exec(char *const exec_array[],
POSIX_CALL(setsid());
#endif
+ reached_preexec = 1;
if (preexec_fn != Py_None && preexec_fn_args_tuple) {
/* This is where the user has asked us to deadlock their program. */
result = PyObject_Call(preexec_fn, preexec_fn_args_tuple, NULL);
@@ -487,6 +488,10 @@ error:
}
unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
unused = write(errpipe_write, ":", 1);
+ if (!reached_preexec) {
+ /* Indicate to the parent that the error happened before exec(). */
+ unused = write(errpipe_write, "noexec", 6);
+ }
/* We can't call strerror(saved_errno). It is not async signal safe.
* The parent process will look the error message up. */
} else {
diff --git a/Objects/longobject.c b/Objects/longobject.c
index dfedfb7..b9a0d85 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -4703,13 +4703,20 @@ static PyGetSetDef long_getset[] = {
};
PyDoc_STRVAR(long_doc,
-"int(x[, base]) -> integer\n\
+"int(x=0) -> integer\n\
+int(x, base=10) -> integer\n\
\n\
-Convert a string or number to an integer, if possible. A floating\n\
-point argument will be truncated towards zero (this does not include a\n\
-string representation of a floating point number!) When converting a\n\
-string, use the optional base. It is an error to supply a base when\n\
-converting a non-string.");
+Convert a number or string to an integer, or return 0 if no arguments\n\
+are given. If x is a number, return x.__int__(). For floating point\n\
+numbers, this truncates towards zero.\n\
+\n\
+If x is not a number or if base is given, then x must be a string,\n\
+bytes, or bytearray instance representing an integer literal in the\n\
+given base. The literal can be preceded by '+' or '-' and be surrounded\n\
+by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\
+Base 0 means to interpret the base from the string as an integer literal.\n\
+>>> int('0b100', base=0)\n\
+4");
static PyNumberMethods long_as_number = {
(binaryfunc)long_add, /*nb_add*/
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 935b205..b67b969 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -135,7 +135,8 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
PyDoc_STRVAR(range_doc,
-"range([start,] stop[, step]) -> range object\n\
+"range(stop) -> range object\n\
+range(start, stop[, step]) -> range object\n\
\n\
Returns a virtual sequence of numbers from start to stop by step.");
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index d7b97c9..0f4b647 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -221,7 +221,8 @@ slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
PyDoc_STRVAR(slice_doc,
-"slice([start,] stop[, step])\n\
+"slice(stop)\n\
+slice(start, stop[, step])\n\
\n\
Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).");
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index f59db36..1dd3a85 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -9986,7 +9986,8 @@ unicode_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
PyDoc_STRVAR(unicode_doc,
- "str(object[, encoding[, errors]]) -> str\n\
+"str(object='') -> str\n\
+str(bytes_or_buffer[, encoding[, errors]]) -> str\n\
\n\
Create a new string object from the given object. If encoding or\n\
errors is specified, then the object must expose a data buffer\n\