From webhook-mailer at python.org Mon Jul 1 02:04:26 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 06:04:26 -0000
Subject: [Python-checkins] bpo-36168: Lowercase the word "subsequent" in
get_value doc (GH-14485)
Message-ID:
https://github.com/python/cpython/commit/12b436e3b079fb3e3a7197c089df90a77e3bdd77
commit: 12b436e3b079fb3e3a7197c089df90a77e3bdd77
branch: master
author: Krishna Oza
committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
date: 2019-06-30T23:04:20-07:00
summary:
bpo-36168: Lowercase the word "subsequent" in get_value doc (GH-14485)
Subsequent -> subsequent
https://bugs.python.org/issue36168
files:
M Doc/library/string.rst
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 288dde6b3fe4..af8b9b358cc3 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -146,7 +146,7 @@ implementation as the built-in :meth:`~str.format` method.
keyword arguments.
For compound field names, these functions are only called for the first
- component of the field name; Subsequent components are handled through
+ component of the field name; subsequent components are handled through
normal attribute and indexing operations.
So for example, the field expression '0.name' would cause
From webhook-mailer at python.org Mon Jul 1 02:29:22 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 06:29:22 -0000
Subject: [Python-checkins] bpo-37428: Don't set PHA verify flag on client
side (GH-14421)
Message-ID:
https://github.com/python/cpython/commit/f0f5930ac88482ef896283db5be9b8d508d077db
commit: f0f5930ac88482ef896283db5be9b8d508d077db
branch: master
author: Christian Heimes
committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
date: 2019-06-30T23:29:17-07:00
summary:
bpo-37428: Don't set PHA verify flag on client side (GH-14421)
SSLContext.post_handshake_auth = True no longer sets
SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
option is documented as ignored for clients, OpenSSL implicitly enables cert
chain validation when the flag is set.
Signed-off-by: Christian Heimes
https://bugs.python.org/issue37428
files:
A Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
M Lib/test/test_ssl.py
M Modules/_ssl.c
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 064f0e8d4de6..d83ee2cc974d 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -4434,6 +4434,37 @@ def test_pha_not_tls13(self):
s.write(b'PHA')
self.assertIn(b'WRONG_SSL_VERSION', s.recv(1024))
+ def test_bpo37428_pha_cert_none(self):
+ # verify that post_handshake_auth does not implicitly enable cert
+ # validation.
+ hostname = SIGNED_CERTFILE_HOSTNAME
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ client_context.post_handshake_auth = True
+ client_context.load_cert_chain(SIGNED_CERTFILE)
+ # no cert validation and CA on client side
+ client_context.check_hostname = False
+ client_context.verify_mode = ssl.CERT_NONE
+
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ server_context.load_verify_locations(SIGNING_CA)
+ server_context.post_handshake_auth = True
+ server_context.verify_mode = ssl.CERT_REQUIRED
+
+ server = ThreadedEchoServer(context=server_context, chatty=False)
+ with server:
+ with client_context.wrap_socket(socket.socket(),
+ server_hostname=hostname) as s:
+ s.connect((HOST, server.port))
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'FALSE\n')
+ s.write(b'PHA')
+ self.assertEqual(s.recv(1024), b'OK\n')
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'TRUE\n')
+ # server cert has not been validated
+ self.assertEqual(s.getpeercert(), {})
+
HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename')
requires_keylog = unittest.skipUnless(
diff --git a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
new file mode 100644
index 000000000000..2cdce6b24dc6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
@@ -0,0 +1,4 @@
+SSLContext.post_handshake_auth = True no longer sets
+SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
+option is documented as ignored for clients, OpenSSL implicitly enables cert
+chain validation when the flag is set.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 2331c58ad77d..3351af6cdefd 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -963,6 +963,26 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
SSL_set_mode(self->ssl,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
+#ifdef TLS1_3_VERSION
+ if (sslctx->post_handshake_auth == 1) {
+ if (socket_type == PY_SSL_SERVER) {
+ /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE.
+ * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and
+ * only in combination with SSL_VERIFY_PEER flag. */
+ int mode = SSL_get_verify_mode(self->ssl);
+ if (mode & SSL_VERIFY_PEER) {
+ int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
+ verify_cb = SSL_get_verify_callback(self->ssl);
+ mode |= SSL_VERIFY_POST_HANDSHAKE;
+ SSL_set_verify(self->ssl, mode, verify_cb);
+ }
+ } else {
+ /* client socket */
+ SSL_set_post_handshake_auth(self->ssl, 1);
+ }
+ }
+#endif
+
if (server_hostname != NULL) {
if (_ssl_configure_hostname(self, server_hostname) < 0) {
Py_DECREF(self);
@@ -2986,10 +3006,10 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n)
"invalid value for verify_mode");
return -1;
}
-#ifdef TLS1_3_VERSION
- if (self->post_handshake_auth)
- mode |= SSL_VERIFY_POST_HANDSHAKE;
-#endif
+
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
+
/* keep current verify cb */
verify_cb = SSL_CTX_get_verify_callback(self->ctx);
SSL_CTX_set_verify(self->ctx, mode, verify_cb);
@@ -3735,8 +3755,6 @@ get_post_handshake_auth(PySSLContext *self, void *c) {
#if TLS1_3_VERSION
static int
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
- int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
- int mode = SSL_CTX_get_verify_mode(self->ctx);
if (arg == NULL) {
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
return -1;
@@ -3748,17 +3766,8 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
}
self->post_handshake_auth = pha;
- /* client-side socket setting, ignored by server-side */
- SSL_CTX_set_post_handshake_auth(self->ctx, pha);
-
- /* server-side socket setting, ignored by client-side */
- verify_cb = SSL_CTX_get_verify_callback(self->ctx);
- if (pha) {
- mode |= SSL_VERIFY_POST_HANDSHAKE;
- } else {
- mode ^= SSL_VERIFY_POST_HANDSHAKE;
- }
- SSL_CTX_set_verify(self->ctx, mode, verify_cb);
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
return 0;
}
From webhook-mailer at python.org Mon Jul 1 02:32:28 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 06:32:28 -0000
Subject: [Python-checkins] bpo-37440: Enable TLS 1.3 post-handshake auth in
http.client (GH-14448)
Message-ID:
https://github.com/python/cpython/commit/d1bd6e79da1ee56dc1b902d804216ffd267399db
commit: d1bd6e79da1ee56dc1b902d804216ffd267399db
branch: master
author: Christian Heimes
committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
date: 2019-06-30T23:32:24-07:00
summary:
bpo-37440: Enable TLS 1.3 post-handshake auth in http.client (GH-14448)
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.
https://bugs.python.org/issue37440
files:
A Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
M Doc/library/http.client.rst
M Lib/http/client.py
M Lib/test/test_httplib.py
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index beaa720d732b..4e761cd39a01 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -94,6 +94,11 @@ The module provides the following classes:
:func:`ssl._create_unverified_context` can be passed to the *context*
parameter.
+ .. versionchanged:: 3.8
+ This class now enables TLS 1.3
+ :attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or
+ when *cert_file* is passed with a custom *context*.
+
.. deprecated:: 3.6
*key_file* and *cert_file* are deprecated in favor of *context*.
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 82908ebe3afd..f61267e108a5 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -1358,6 +1358,9 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
self.cert_file = cert_file
if context is None:
context = ssl._create_default_https_context()
+ # enable PHA for TLS 1.3 connections if available
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
will_verify = context.verify_mode != ssl.CERT_NONE
if check_hostname is None:
check_hostname = context.check_hostname
@@ -1366,6 +1369,10 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
"either CERT_OPTIONAL or CERT_REQUIRED")
if key_file or cert_file:
context.load_cert_chain(cert_file, key_file)
+ # cert and key file means the user wants to authenticate.
+ # enable TLS 1.3 PHA implicitly even for custom contexts.
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
self._context = context
if check_hostname is not None:
self._context.check_hostname = check_hostname
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 968cbd86a1e4..9148169cc7c2 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -1745,6 +1745,24 @@ def test_host_port(self):
self.assertEqual(h, c.host)
self.assertEqual(p, c.port)
+ def test_tls13_pha(self):
+ import ssl
+ if not ssl.HAS_TLSv1_3:
+ self.skipTest('TLS 1.3 support required')
+ # just check status of PHA flag
+ h = client.HTTPSConnection('localhost', 443)
+ self.assertTrue(h._context.post_handshake_auth)
+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ self.assertFalse(context.post_handshake_auth)
+ h = client.HTTPSConnection('localhost', 443, context=context)
+ self.assertIs(h._context, context)
+ self.assertFalse(h._context.post_handshake_auth)
+
+ h = client.HTTPSConnection('localhost', 443, context=context,
+ cert_file=CERT_localhost)
+ self.assertTrue(h._context.post_handshake_auth)
+
class RequestBodyTest(TestCase):
"""Test cases where a request includes a message body."""
diff --git a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
new file mode 100644
index 000000000000..b336e061e15e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
@@ -0,0 +1,2 @@
+http.client now enables TLS 1.3 post-handshake authentication for default
+context or if a cert_file is passed to HTTPSConnection.
From webhook-mailer at python.org Mon Jul 1 02:51:44 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 06:51:44 -0000
Subject: [Python-checkins] [3.7] bpo-37428: Don't set PHA verify flag on
client side (GH-14421) (GH-14493)
Message-ID:
https://github.com/python/cpython/commit/cf7617460a920dd75ced017792045d3ae77648ad
commit: cf7617460a920dd75ced017792045d3ae77648ad
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-06-30T23:51:40-07:00
summary:
[3.7] bpo-37428: Don't set PHA verify flag on client side (GH-14421) (GH-14493)
SSLContext.post_handshake_auth = True no longer sets
SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
option is documented as ignored for clients, OpenSSL implicitly enables cert
chain validation when the flag is set.
Signed-off-by: Christian Heimes
https://bugs.python.org/issue37428
(cherry picked from commit f0f5930ac88482ef896283db5be9b8d508d077db)
Co-authored-by: Christian Heimes
https://bugs.python.org/issue37428
files:
A Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
M Lib/test/test_ssl.py
M Modules/_ssl.c
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 73b6bdf01e7f..86f790b4a22e 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -4437,6 +4437,37 @@ def test_pha_not_tls13(self):
s.write(b'PHA')
self.assertIn(b'WRONG_SSL_VERSION', s.recv(1024))
+ def test_bpo37428_pha_cert_none(self):
+ # verify that post_handshake_auth does not implicitly enable cert
+ # validation.
+ hostname = SIGNED_CERTFILE_HOSTNAME
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ client_context.post_handshake_auth = True
+ client_context.load_cert_chain(SIGNED_CERTFILE)
+ # no cert validation and CA on client side
+ client_context.check_hostname = False
+ client_context.verify_mode = ssl.CERT_NONE
+
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ server_context.load_verify_locations(SIGNING_CA)
+ server_context.post_handshake_auth = True
+ server_context.verify_mode = ssl.CERT_REQUIRED
+
+ server = ThreadedEchoServer(context=server_context, chatty=False)
+ with server:
+ with client_context.wrap_socket(socket.socket(),
+ server_hostname=hostname) as s:
+ s.connect((HOST, server.port))
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'FALSE\n')
+ s.write(b'PHA')
+ self.assertEqual(s.recv(1024), b'OK\n')
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'TRUE\n')
+ # server cert has not been validated
+ self.assertEqual(s.getpeercert(), {})
+
def test_main(verbose=False):
if support.verbose:
diff --git a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
new file mode 100644
index 000000000000..2cdce6b24dc6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
@@ -0,0 +1,4 @@
+SSLContext.post_handshake_auth = True no longer sets
+SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
+option is documented as ignored for clients, OpenSSL implicitly enables cert
+chain validation when the flag is set.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 30c91f59310f..e8955eedfa53 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -931,6 +931,26 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
SSL_set_mode(self->ssl,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
+#ifdef TLS1_3_VERSION
+ if (sslctx->post_handshake_auth == 1) {
+ if (socket_type == PY_SSL_SERVER) {
+ /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE.
+ * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and
+ * only in combination with SSL_VERIFY_PEER flag. */
+ int mode = SSL_get_verify_mode(self->ssl);
+ if (mode & SSL_VERIFY_PEER) {
+ int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
+ verify_cb = SSL_get_verify_callback(self->ssl);
+ mode |= SSL_VERIFY_POST_HANDSHAKE;
+ SSL_set_verify(self->ssl, mode, verify_cb);
+ }
+ } else {
+ /* client socket */
+ SSL_set_post_handshake_auth(self->ssl, 1);
+ }
+ }
+#endif
+
if (server_hostname != NULL) {
if (_ssl_configure_hostname(self, server_hostname) < 0) {
Py_DECREF(self);
@@ -2928,10 +2948,10 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n)
"invalid value for verify_mode");
return -1;
}
-#ifdef TLS1_3_VERSION
- if (self->post_handshake_auth)
- mode |= SSL_VERIFY_POST_HANDSHAKE;
-#endif
+
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
+
/* keep current verify cb */
verify_cb = SSL_CTX_get_verify_callback(self->ctx);
SSL_CTX_set_verify(self->ctx, mode, verify_cb);
@@ -3628,8 +3648,6 @@ get_post_handshake_auth(PySSLContext *self, void *c) {
#if TLS1_3_VERSION
static int
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
- int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
- int mode = SSL_CTX_get_verify_mode(self->ctx);
if (arg == NULL) {
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
return -1;
@@ -3641,17 +3659,8 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
}
self->post_handshake_auth = pha;
- /* client-side socket setting, ignored by server-side */
- SSL_CTX_set_post_handshake_auth(self->ctx, pha);
-
- /* server-side socket setting, ignored by client-side */
- verify_cb = SSL_CTX_get_verify_callback(self->ctx);
- if (pha) {
- mode |= SSL_VERIFY_POST_HANDSHAKE;
- } else {
- mode ^= SSL_VERIFY_POST_HANDSHAKE;
- }
- SSL_CTX_set_verify(self->ctx, mode, verify_cb);
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
return 0;
}
From webhook-mailer at python.org Mon Jul 1 03:07:50 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 07:07:50 -0000
Subject: [Python-checkins] [3.8] bpo-37440: Enable TLS 1.3 post-handshake
auth in http.client (GH-14448) (GH-14495)
Message-ID:
https://github.com/python/cpython/commit/ee72dda9616258b57c19eb5af00f3e80a3fb8e22
commit: ee72dda9616258b57c19eb5af00f3e80a3fb8e22
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T00:07:44-07:00
summary:
[3.8] bpo-37440: Enable TLS 1.3 post-handshake auth in http.client (GH-14448) (GH-14495)
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.
https://bugs.python.org/issue37440
(cherry picked from commit d1bd6e79da1ee56dc1b902d804216ffd267399db)
Co-authored-by: Christian Heimes
https://bugs.python.org/issue37440
files:
A Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
M Doc/library/http.client.rst
M Lib/http/client.py
M Lib/test/test_httplib.py
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index beaa720d732b..4e761cd39a01 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -94,6 +94,11 @@ The module provides the following classes:
:func:`ssl._create_unverified_context` can be passed to the *context*
parameter.
+ .. versionchanged:: 3.8
+ This class now enables TLS 1.3
+ :attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or
+ when *cert_file* is passed with a custom *context*.
+
.. deprecated:: 3.6
*key_file* and *cert_file* are deprecated in favor of *context*.
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 82908ebe3afd..f61267e108a5 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -1358,6 +1358,9 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
self.cert_file = cert_file
if context is None:
context = ssl._create_default_https_context()
+ # enable PHA for TLS 1.3 connections if available
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
will_verify = context.verify_mode != ssl.CERT_NONE
if check_hostname is None:
check_hostname = context.check_hostname
@@ -1366,6 +1369,10 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
"either CERT_OPTIONAL or CERT_REQUIRED")
if key_file or cert_file:
context.load_cert_chain(cert_file, key_file)
+ # cert and key file means the user wants to authenticate.
+ # enable TLS 1.3 PHA implicitly even for custom contexts.
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
self._context = context
if check_hostname is not None:
self._context.check_hostname = check_hostname
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 968cbd86a1e4..9148169cc7c2 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -1745,6 +1745,24 @@ def test_host_port(self):
self.assertEqual(h, c.host)
self.assertEqual(p, c.port)
+ def test_tls13_pha(self):
+ import ssl
+ if not ssl.HAS_TLSv1_3:
+ self.skipTest('TLS 1.3 support required')
+ # just check status of PHA flag
+ h = client.HTTPSConnection('localhost', 443)
+ self.assertTrue(h._context.post_handshake_auth)
+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ self.assertFalse(context.post_handshake_auth)
+ h = client.HTTPSConnection('localhost', 443, context=context)
+ self.assertIs(h._context, context)
+ self.assertFalse(h._context.post_handshake_auth)
+
+ h = client.HTTPSConnection('localhost', 443, context=context,
+ cert_file=CERT_localhost)
+ self.assertTrue(h._context.post_handshake_auth)
+
class RequestBodyTest(TestCase):
"""Test cases where a request includes a message body."""
diff --git a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
new file mode 100644
index 000000000000..b336e061e15e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
@@ -0,0 +1,2 @@
+http.client now enables TLS 1.3 post-handshake authentication for default
+context or if a cert_file is passed to HTTPSConnection.
From webhook-mailer at python.org Mon Jul 1 03:07:56 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 07:07:56 -0000
Subject: [Python-checkins] [3.7] bpo-37440: Enable TLS 1.3 post-handshake
auth in http.client (GH-14448) (GH-14496)
Message-ID:
https://github.com/python/cpython/commit/6be91102f75aa4b4b8c1e55960aa22008ff9e319
commit: 6be91102f75aa4b4b8c1e55960aa22008ff9e319
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T00:07:52-07:00
summary:
[3.7] bpo-37440: Enable TLS 1.3 post-handshake auth in http.client (GH-14448) (GH-14496)
Post-handshake authentication is required for conditional client cert authentication with TLS 1.3.
https://bugs.python.org/issue37440
(cherry picked from commit d1bd6e79da1ee56dc1b902d804216ffd267399db)
Co-authored-by: Christian Heimes
https://bugs.python.org/issue37440
files:
A Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
M Doc/library/http.client.rst
M Lib/http/client.py
M Lib/test/test_httplib.py
diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst
index 3408c103e2f3..3ebeb10aee9a 100644
--- a/Doc/library/http.client.rst
+++ b/Doc/library/http.client.rst
@@ -94,6 +94,11 @@ The module provides the following classes:
:func:`ssl._create_unverified_context` can be passed to the *context*
parameter.
+ .. versionchanged:: 3.7.4
+ This class now enables TLS 1.3
+ :attr:`ssl.SSLContext.post_handshake_auth` for the default *context* or
+ when *cert_file* is passed with a custom *context*.
+
.. deprecated:: 3.6
*key_file* and *cert_file* are deprecated in favor of *context*.
diff --git a/Lib/http/client.py b/Lib/http/client.py
index 2afd452fe30f..dd23edcd597c 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -1381,6 +1381,9 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
self.cert_file = cert_file
if context is None:
context = ssl._create_default_https_context()
+ # enable PHA for TLS 1.3 connections if available
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
will_verify = context.verify_mode != ssl.CERT_NONE
if check_hostname is None:
check_hostname = context.check_hostname
@@ -1389,6 +1392,10 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
"either CERT_OPTIONAL or CERT_REQUIRED")
if key_file or cert_file:
context.load_cert_chain(cert_file, key_file)
+ # cert and key file means the user wants to authenticate.
+ # enable TLS 1.3 PHA implicitly even for custom contexts.
+ if context.post_handshake_auth is not None:
+ context.post_handshake_auth = True
self._context = context
if check_hostname is not None:
self._context.check_hostname = check_hostname
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 49263a8a3a0d..c4246671586f 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -1748,6 +1748,24 @@ def test_host_port(self):
self.assertEqual(h, c.host)
self.assertEqual(p, c.port)
+ def test_tls13_pha(self):
+ import ssl
+ if not ssl.HAS_TLSv1_3:
+ self.skipTest('TLS 1.3 support required')
+ # just check status of PHA flag
+ h = client.HTTPSConnection('localhost', 443)
+ self.assertTrue(h._context.post_handshake_auth)
+
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ self.assertFalse(context.post_handshake_auth)
+ h = client.HTTPSConnection('localhost', 443, context=context)
+ self.assertIs(h._context, context)
+ self.assertFalse(h._context.post_handshake_auth)
+
+ h = client.HTTPSConnection('localhost', 443, context=context,
+ cert_file=CERT_localhost)
+ self.assertTrue(h._context.post_handshake_auth)
+
class RequestBodyTest(TestCase):
"""Test cases where a request includes a message body."""
diff --git a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
new file mode 100644
index 000000000000..b336e061e15e
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst
@@ -0,0 +1,2 @@
+http.client now enables TLS 1.3 post-handshake authentication for default
+context or if a cert_file is passed to HTTPSConnection.
From webhook-mailer at python.org Mon Jul 1 03:25:54 2019
From: webhook-mailer at python.org (Christian Heimes)
Date: Mon, 01 Jul 2019 07:25:54 -0000
Subject: [Python-checkins] [3.8] bpo-37428: Don't set PHA verify flag on
client side (GH-14494)
Message-ID:
https://github.com/python/cpython/commit/f22c4cf11d10f52faa86e0b308dd28f11819efd8
commit: f22c4cf11d10f52faa86e0b308dd28f11819efd8
branch: 3.8
author: Christian Heimes
committer: GitHub
date: 2019-07-01T09:25:48+02:00
summary:
[3.8] bpo-37428: Don't set PHA verify flag on client side (GH-14494)
SSLContext.post_handshake_auth = True no longer sets
SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
option is documented as ignored for clients, OpenSSL implicitly enables cert
chain validation when the flag is set.
Signed-off-by: Christian Heimes
https://bugs.python.org/issue37428
(cherry picked from commit f0f5930ac88482ef896283db5be9b8d508d077db)
files:
A Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
M Lib/test/test_ssl.py
M Modules/_ssl.c
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 38fdf3f375cc..66369fe60dfe 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -4428,6 +4428,37 @@ def test_pha_not_tls13(self):
s.write(b'PHA')
self.assertIn(b'WRONG_SSL_VERSION', s.recv(1024))
+ def test_bpo37428_pha_cert_none(self):
+ # verify that post_handshake_auth does not implicitly enable cert
+ # validation.
+ hostname = SIGNED_CERTFILE_HOSTNAME
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ client_context.post_handshake_auth = True
+ client_context.load_cert_chain(SIGNED_CERTFILE)
+ # no cert validation and CA on client side
+ client_context.check_hostname = False
+ client_context.verify_mode = ssl.CERT_NONE
+
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ server_context.load_cert_chain(SIGNED_CERTFILE)
+ server_context.load_verify_locations(SIGNING_CA)
+ server_context.post_handshake_auth = True
+ server_context.verify_mode = ssl.CERT_REQUIRED
+
+ server = ThreadedEchoServer(context=server_context, chatty=False)
+ with server:
+ with client_context.wrap_socket(socket.socket(),
+ server_hostname=hostname) as s:
+ s.connect((HOST, server.port))
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'FALSE\n')
+ s.write(b'PHA')
+ self.assertEqual(s.recv(1024), b'OK\n')
+ s.write(b'HASCERT')
+ self.assertEqual(s.recv(1024), b'TRUE\n')
+ # server cert has not been validated
+ self.assertEqual(s.getpeercert(), {})
+
HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename')
requires_keylog = unittest.skipUnless(
diff --git a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
new file mode 100644
index 000000000000..2cdce6b24dc6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst
@@ -0,0 +1,4 @@
+SSLContext.post_handshake_auth = True no longer sets
+SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the
+option is documented as ignored for clients, OpenSSL implicitly enables cert
+chain validation when the flag is set.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 2331c58ad77d..3351af6cdefd 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -963,6 +963,26 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
SSL_set_mode(self->ssl,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
+#ifdef TLS1_3_VERSION
+ if (sslctx->post_handshake_auth == 1) {
+ if (socket_type == PY_SSL_SERVER) {
+ /* bpo-37428: OpenSSL does not ignore SSL_VERIFY_POST_HANDSHAKE.
+ * Set SSL_VERIFY_POST_HANDSHAKE flag only for server sockets and
+ * only in combination with SSL_VERIFY_PEER flag. */
+ int mode = SSL_get_verify_mode(self->ssl);
+ if (mode & SSL_VERIFY_PEER) {
+ int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
+ verify_cb = SSL_get_verify_callback(self->ssl);
+ mode |= SSL_VERIFY_POST_HANDSHAKE;
+ SSL_set_verify(self->ssl, mode, verify_cb);
+ }
+ } else {
+ /* client socket */
+ SSL_set_post_handshake_auth(self->ssl, 1);
+ }
+ }
+#endif
+
if (server_hostname != NULL) {
if (_ssl_configure_hostname(self, server_hostname) < 0) {
Py_DECREF(self);
@@ -2986,10 +3006,10 @@ _set_verify_mode(PySSLContext *self, enum py_ssl_cert_requirements n)
"invalid value for verify_mode");
return -1;
}
-#ifdef TLS1_3_VERSION
- if (self->post_handshake_auth)
- mode |= SSL_VERIFY_POST_HANDSHAKE;
-#endif
+
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
+
/* keep current verify cb */
verify_cb = SSL_CTX_get_verify_callback(self->ctx);
SSL_CTX_set_verify(self->ctx, mode, verify_cb);
@@ -3735,8 +3755,6 @@ get_post_handshake_auth(PySSLContext *self, void *c) {
#if TLS1_3_VERSION
static int
set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
- int (*verify_cb)(int, X509_STORE_CTX *) = NULL;
- int mode = SSL_CTX_get_verify_mode(self->ctx);
if (arg == NULL) {
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
return -1;
@@ -3748,17 +3766,8 @@ set_post_handshake_auth(PySSLContext *self, PyObject *arg, void *c) {
}
self->post_handshake_auth = pha;
- /* client-side socket setting, ignored by server-side */
- SSL_CTX_set_post_handshake_auth(self->ctx, pha);
-
- /* server-side socket setting, ignored by client-side */
- verify_cb = SSL_CTX_get_verify_callback(self->ctx);
- if (pha) {
- mode |= SSL_VERIFY_POST_HANDSHAKE;
- } else {
- mode ^= SSL_VERIFY_POST_HANDSHAKE;
- }
- SSL_CTX_set_verify(self->ctx, mode, verify_cb);
+ /* bpo-37428: newPySSLSocket() sets SSL_VERIFY_POST_HANDSHAKE flag for
+ * server sockets and SSL_set_post_handshake_auth() for client. */
return 0;
}
From webhook-mailer at python.org Mon Jul 1 05:53:48 2019
From: webhook-mailer at python.org (Ned Deily)
Date: Mon, 01 Jul 2019 09:53:48 -0000
Subject: [Python-checkins] Minor updates to the macOS installer screens for
3.8.0b2 (GH-14501)
Message-ID:
https://github.com/python/cpython/commit/fc1fbe6099e826e8304eadf781af7c10d739fc40
commit: fc1fbe6099e826e8304eadf781af7c10d739fc40
branch: master
author: Ned Deily
committer: GitHub
date: 2019-07-01T05:53:42-04:00
summary:
Minor updates to the macOS installer screens for 3.8.0b2 (GH-14501)
files:
M Mac/BuildScript/resources/ReadMe.rtf
M Mac/BuildScript/resources/Welcome.rtf
diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf
index ab7aeff5376c..ec83750c6e69 100644
--- a/Mac/BuildScript/resources/ReadMe.rtf
+++ b/Mac/BuildScript/resources/ReadMe.rtf
@@ -1,4 +1,4 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf500
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique;
\f3\fmodern\fcharset0 CourierNewPSMT;}
{\colortbl;\red255\green255\blue255;}
@@ -8,12 +8,18 @@
\f0\fs24 \cf0 This package will install Python $FULL_VERSION for macOS $MACOSX_DEPLOYMENT_TARGET for the following architecture(s): $ARCHITECTURES.\
\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0
+
+\f1\b \cf0 NOTE:
+\f0\b0 This is a beta test preview of Python 3.8.0, the next feature release of Python 3.8. It is not intended for production use.\
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
+\cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\f1\b \cf0 \ul \ulc0 Certificate verification and OpenSSL\
\f0\b0 \ulnone \
-This package includes its own private copy of OpenSSL 1.1.0. The trust certificates in system and user keychains managed by the
+This package includes its own private copy of OpenSSL 1.1.1. The trust certificates in system and user keychains managed by the
\f2\i Keychain Access
\f0\i0 application and the
\f2\i security
diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf
index df5d20da9ebb..053084d0425b 100644
--- a/Mac/BuildScript/resources/Welcome.rtf
+++ b/Mac/BuildScript/resources/Welcome.rtf
@@ -1,5 +1,6 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200
-\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;}
+{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf500
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT;
+}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0
@@ -17,7 +18,11 @@
\f1\b IDLE
\f0\b0 .\
\
+At the end of this install, click on
+\f2 Install Certificates
+\f0 for SSL root certificates\
+\
\f1\b NOTE:
-\f0\b0 This is an alpha test preview of Python 3.8.0, the next feature release of Python 3.8. It is not intended for production use.\
+\f0\b0 This is a beta test preview of Python 3.8.0, the next feature release of Python 3.8. It is not intended for production use.\
}
\ No newline at end of file
From webhook-mailer at python.org Mon Jul 1 06:35:11 2019
From: webhook-mailer at python.org (Petr Viktorin)
Date: Mon, 01 Jul 2019 10:35:11 -0000
Subject: [Python-checkins] bpo-37221: Add PyCode_NewWithPosOnlyArgs to be
used internally and set PyCode_New as a compatibility wrapper (GH-13959)
Message-ID:
https://github.com/python/cpython/commit/4a2edc34a405150d0b23ecfdcb401e7cf59f4650
commit: 4a2edc34a405150d0b23ecfdcb401e7cf59f4650
branch: master
author: Pablo Galindo
committer: Petr Viktorin
date: 2019-07-01T12:35:05+02:00
summary:
bpo-37221: Add PyCode_NewWithPosOnlyArgs to be used internally and set PyCode_New as a compatibility wrapper (GH-13959)
Add PyCode_NewEx to be used internally and set PyCode_New as a compatibility wrapper
files:
A Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst
M Doc/c-api/code.rst
M Doc/data/refcounts.dat
M Doc/whatsnew/3.8.rst
M Include/code.h
M Objects/codeobject.c
M Python/compile.c
M Python/marshal.c
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index 7353df56e7d3..3c4f66923da5 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -33,20 +33,21 @@ bound into a function.
Return the number of free variables in *co*.
-.. c:function:: PyCodeObject* PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
+.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
- Return a new code object. If you need a dummy code object to
- create a frame, use :c:func:`PyCode_NewEmpty` instead. Calling
- :c:func:`PyCode_New` directly can bind you to a precise Python
- version since the definition of the bytecode changes often.
-
- .. versionchanged:: 3.8
- An extra parameter is required (*posonlyargcount*) to support :PEP:`570`.
- The first parameter (*argcount*) now represents the total number of positional arguments,
- including positional-only.
+ Return a new code object. If you need a dummy code object to create a frame,
+ use :c:func:`PyCode_NewEmpty` instead. Calling :c:func:`PyCode_New` directly
+ can bind you to a precise Python version since the definition of the bytecode
+ changes often.
.. audit-event:: code.__new__ code,filename,name,argcount,posonlyargcount,kwonlyargcount,nlocals,stacksize,flags c.PyCode_New
+.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab)
+
+ Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positonal-only arguments.
+
+ .. versionadded:: 3.8
+
.. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
Return a new empty code object with the specified filename,
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index aca57a1dae9d..fda347eab102 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -234,9 +234,26 @@ PyCode_Check:PyObject*:co:0:
PyCode_GetNumFree:int:::
PyCode_GetNumFree:PyCodeObject*:co:0:
+PyCode_NewWithPosOnlyArgs:PyCodeObject*::+1:
+PyCode_NewWithPosOnlyArgs:int:argcount::
+PyCode_NewWithPosOnlyArgs:int:posonlyargcount::
+PyCode_NewWithPosOnlyArgs:int:kwonlyargcount::
+PyCode_NewWithPosOnlyArgs:int:nlocals::
+PyCode_NewWithPosOnlyArgs:int:stacksize::
+PyCode_NewWithPosOnlyArgs:int:flags::
+PyCode_NewWithPosOnlyArgs:PyObject*:code:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:consts:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:names:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:varnames:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:freevars:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:cellvars:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:filename:0:
+PyCode_NewWithPosOnlyArgs:PyObject*:name:0:
+PyCode_NewWithPosOnlyArgs:int:firstlineno::
+PyCode_NewWithPosOnlyArgs:PyObject*:lnotab:0:
+
PyCode_New:PyCodeObject*::+1:
PyCode_New:int:argcount::
-PyCode_New:int:posonlyargcount::
PyCode_New:int:kwonlyargcount::
PyCode_New:int:nlocals::
PyCode_New:int:stacksize::
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 46e531f58995..5aab191f1a48 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -1045,6 +1045,11 @@ Build and C API Changes
allocation or deallocation may need to be adjusted.
(Contributed by Eddie Elizondo in :issue:`35810`.)
+* The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create
+ code objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount*
+ parameter for indicating the number of positional-only arguments.
+ (Contributed by Pablo Galindo in :issue:`37221`.)
+
Deprecated
==========
diff --git a/Include/code.h b/Include/code.h
index b79d977394e0..3afddd20c80d 100644
--- a/Include/code.h
+++ b/Include/code.h
@@ -120,6 +120,11 @@ PyAPI_DATA(PyTypeObject) PyCode_Type;
/* Public interface */
PyAPI_FUNC(PyCodeObject *) PyCode_New(
+ int, int, int, int, int, PyObject *, PyObject *,
+ PyObject *, PyObject *, PyObject *, PyObject *,
+ PyObject *, PyObject *, int, PyObject *);
+
+PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs(
int, int, int, int, int, int, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, int, PyObject *);
diff --git a/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst b/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst
new file mode 100644
index 000000000000..0ea8b9b86788
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst
@@ -0,0 +1,3 @@
+The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create
+code objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount*
+parameter for indicating the number of positonal-only arguments.
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 1333cc833e1e..39bf6fc6f228 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -102,14 +102,13 @@ intern_string_constants(PyObject *tuple)
return modified;
}
-
PyCodeObject *
-PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount,
- int nlocals, int stacksize, int flags,
- PyObject *code, PyObject *consts, PyObject *names,
- PyObject *varnames, PyObject *freevars, PyObject *cellvars,
- PyObject *filename, PyObject *name, int firstlineno,
- PyObject *lnotab)
+PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
+ int nlocals, int stacksize, int flags,
+ PyObject *code, PyObject *consts, PyObject *names,
+ PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+ PyObject *filename, PyObject *name, int firstlineno,
+ PyObject *lnotab)
{
PyCodeObject *co;
Py_ssize_t *cell2arg = NULL;
@@ -243,6 +242,20 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount,
return co;
}
+PyCodeObject *
+PyCode_New(int argcount, int kwonlyargcount,
+ int nlocals, int stacksize, int flags,
+ PyObject *code, PyObject *consts, PyObject *names,
+ PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+ PyObject *filename, PyObject *name, int firstlineno,
+ PyObject *lnotab)
+{
+ return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
+ stacksize, flags, code, consts, names,
+ varnames, freevars, cellvars, filename,
+ name, firstlineno, lnotab);
+}
+
int
_PyCode_InitOpcache(PyCodeObject *co)
{
@@ -311,7 +324,8 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
if (filename_ob == NULL)
goto failed;
- result = PyCode_New(0, /* argcount */
+ result = PyCode_NewWithPosOnlyArgs(
+ 0, /* argcount */
0, /* posonlyargcount */
0, /* kwonlyargcount */
0, /* nlocals */
@@ -492,12 +506,14 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (ourcellvars == NULL)
goto cleanup;
- co = (PyObject *)PyCode_New(argcount, posonlyargcount, kwonlyargcount,
- nlocals, stacksize, flags,
- code, consts, ournames, ourvarnames,
- ourfreevars, ourcellvars, filename,
- name, firstlineno, lnotab);
- cleanup:
+ co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount,
+ kwonlyargcount,
+ nlocals, stacksize, flags,
+ code, consts, ournames,
+ ourvarnames, ourfreevars,
+ ourcellvars, filename,
+ name, firstlineno, lnotab);
+ cleanup:
Py_XDECREF(ournames);
Py_XDECREF(ourvarnames);
Py_XDECREF(ourfreevars);
@@ -625,7 +641,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
#undef CHECK_INT_ARG
- return (PyObject *)PyCode_New(
+ return (PyObject *)PyCode_NewWithPosOnlyArgs(
co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
co_varnames, co_freevars, co_cellvars, co_filename, co_name,
diff --git a/Python/compile.c b/Python/compile.c
index 7bdf406079d3..9cce8aeb4e1f 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -5813,13 +5813,11 @@ makecode(struct compiler *c, struct assembler *a)
if (maxdepth < 0) {
goto error;
}
- co = PyCode_New(posonlyargcount+posorkeywordargcount, posonlyargcount,
- kwonlyargcount, nlocals_int, maxdepth, flags,
- bytecode, consts, names, varnames,
- freevars, cellvars,
- c->c_filename, c->u->u_name,
- c->u->u_firstlineno,
- a->a_lnotab);
+ co = PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount,
+ posonlyargcount, kwonlyargcount, nlocals_int,
+ maxdepth, flags, bytecode, consts, names,
+ varnames, freevars, cellvars, c->c_filename,
+ c->u->u_name, c->u->u_firstlineno, a->a_lnotab);
error:
Py_XDECREF(consts);
Py_XDECREF(names);
diff --git a/Python/marshal.c b/Python/marshal.c
index caaddfe9e44e..b2daff2c8a3b 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -1396,7 +1396,7 @@ r_object(RFILE *p)
if (lnotab == NULL)
goto code_error;
- v = (PyObject *) PyCode_New(
+ v = (PyObject *) PyCode_NewWithPosOnlyArgs(
argcount, posonlyargcount, kwonlyargcount,
nlocals, stacksize, flags,
code, consts, names, varnames,
From webhook-mailer at python.org Mon Jul 1 07:41:25 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 11:41:25 -0000
Subject: [Python-checkins] bpo-32934: Clarified meaning of 'capacity' for
BufferingHandler and MemoryHandler. (GH-14498)
Message-ID:
https://github.com/python/cpython/commit/84de34e39eb9e49b2ae691c6f67df8d7da3561de
commit: 84de34e39eb9e49b2ae691c6f67df8d7da3561de
branch: master
author: Vinay Sajip
committer: GitHub
date: 2019-07-01T12:41:21+01:00
summary:
bpo-32934: Clarified meaning of 'capacity' for BufferingHandler and MemoryHandler. (GH-14498)
files:
M Doc/howto/logging-cookbook.rst
M Doc/library/logging.handlers.rst
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 71f9fc920fdf..87ac79ef8072 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -2266,9 +2266,9 @@ The script just arranges to decorate ``foo`` with a decorator which will do the
conditional logging that's required. The decorator takes a logger as a parameter
and attaches a memory handler for the duration of the call to the decorated
function. The decorator can be additionally parameterised using a target handler,
-a level at which flushing should occur, and a capacity for the buffer. These
-default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``,
-``logging.ERROR`` and ``100`` respectively.
+a level at which flushing should occur, and a capacity for the buffer (number of
+records buffered). These default to a :class:`~logging.StreamHandler` which
+writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively.
Here's the script::
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 703d66d7ff6a..df5bfefaa275 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -861,7 +861,8 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: BufferingHandler(capacity)
- Initializes the handler with a buffer of the specified capacity.
+ Initializes the handler with a buffer of the specified capacity. Here,
+ *capacity* means the number of logging records buffered.
.. method:: emit(record)
@@ -885,12 +886,13 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)
Returns a new instance of the :class:`MemoryHandler` class. The instance is
- initialized with a buffer size of *capacity*. If *flushLevel* is not specified,
- :const:`ERROR` is used. If no *target* is specified, the target will need to be
- set using :meth:`setTarget` before this handler does anything useful. If
- *flushOnClose* is specified as ``False``, then the buffer is *not* flushed when
- the handler is closed. If not specified or specified as ``True``, the previous
- behaviour of flushing the buffer will occur when the handler is closed.
+ initialized with a buffer size of *capacity* (number of records buffered).
+ If *flushLevel* is not specified, :const:`ERROR` is used. If no *target* is
+ specified, the target will need to be set using :meth:`setTarget` before this
+ handler does anything useful. If *flushOnClose* is specified as ``False``,
+ then the buffer is *not* flushed when the handler is closed. If not specified
+ or specified as ``True``, the previous behaviour of flushing the buffer will
+ occur when the handler is closed.
.. versionchanged:: 3.6
The *flushOnClose* parameter was added.
From webhook-mailer at python.org Mon Jul 1 08:12:03 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 12:12:03 -0000
Subject: [Python-checkins] bpo-32934: Clarified meaning of 'capacity' for
BufferingHandler and MemoryHandler. (GH-14498) (GH-14508)
Message-ID:
https://github.com/python/cpython/commit/471d785dc759eb2e9c06f077f323cf136d32506b
commit: 471d785dc759eb2e9c06f077f323cf136d32506b
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T13:11:37+01:00
summary:
bpo-32934: Clarified meaning of 'capacity' for BufferingHandler and MemoryHandler. (GH-14498) (GH-14508)
(cherry picked from commit 84de34e39eb9e49b2ae691c6f67df8d7da3561de)
files:
M Doc/howto/logging-cookbook.rst
M Doc/library/logging.handlers.rst
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index e391506ce2e4..105ae5ed25a0 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -2267,9 +2267,9 @@ The script just arranges to decorate ``foo`` with a decorator which will do the
conditional logging that's required. The decorator takes a logger as a parameter
and attaches a memory handler for the duration of the call to the decorated
function. The decorator can be additionally parameterised using a target handler,
-a level at which flushing should occur, and a capacity for the buffer. These
-default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``,
-``logging.ERROR`` and ``100`` respectively.
+a level at which flushing should occur, and a capacity for the buffer (number of
+records buffered). These default to a :class:`~logging.StreamHandler` which
+writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively.
Here's the script::
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index b48d50f9e9e5..b2ebafa83b2e 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -840,7 +840,8 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: BufferingHandler(capacity)
- Initializes the handler with a buffer of the specified capacity.
+ Initializes the handler with a buffer of the specified capacity. Here,
+ *capacity* means the number of logging records buffered.
.. method:: emit(record)
@@ -864,12 +865,13 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)
Returns a new instance of the :class:`MemoryHandler` class. The instance is
- initialized with a buffer size of *capacity*. If *flushLevel* is not specified,
- :const:`ERROR` is used. If no *target* is specified, the target will need to be
- set using :meth:`setTarget` before this handler does anything useful. If
- *flushOnClose* is specified as ``False``, then the buffer is *not* flushed when
- the handler is closed. If not specified or specified as ``True``, the previous
- behaviour of flushing the buffer will occur when the handler is closed.
+ initialized with a buffer size of *capacity* (number of records buffered).
+ If *flushLevel* is not specified, :const:`ERROR` is used. If no *target* is
+ specified, the target will need to be set using :meth:`setTarget` before this
+ handler does anything useful. If *flushOnClose* is specified as ``False``,
+ then the buffer is *not* flushed when the handler is closed. If not specified
+ or specified as ``True``, the previous behaviour of flushing the buffer will
+ occur when the handler is closed.
.. versionchanged:: 3.6
The *flushOnClose* parameter was added.
From webhook-mailer at python.org Mon Jul 1 08:12:14 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 12:12:14 -0000
Subject: [Python-checkins] bpo-32934: Clarified meaning of 'capacity' for
BufferingHandler and MemoryHandler. (GH-14498) (GH-14507)
Message-ID:
https://github.com/python/cpython/commit/3db5c5c7630af92336a8c0a269e05607cd68f9e7
commit: 3db5c5c7630af92336a8c0a269e05607cd68f9e7
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T13:12:08+01:00
summary:
bpo-32934: Clarified meaning of 'capacity' for BufferingHandler and MemoryHandler. (GH-14498) (GH-14507)
(cherry picked from commit 84de34e39eb9e49b2ae691c6f67df8d7da3561de)
files:
M Doc/howto/logging-cookbook.rst
M Doc/library/logging.handlers.rst
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 71f9fc920fdf..87ac79ef8072 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -2266,9 +2266,9 @@ The script just arranges to decorate ``foo`` with a decorator which will do the
conditional logging that's required. The decorator takes a logger as a parameter
and attaches a memory handler for the duration of the call to the decorated
function. The decorator can be additionally parameterised using a target handler,
-a level at which flushing should occur, and a capacity for the buffer. These
-default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``,
-``logging.ERROR`` and ``100`` respectively.
+a level at which flushing should occur, and a capacity for the buffer (number of
+records buffered). These default to a :class:`~logging.StreamHandler` which
+writes to ``sys.stderr``, ``logging.ERROR`` and ``100`` respectively.
Here's the script::
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index b48d50f9e9e5..b2ebafa83b2e 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -840,7 +840,8 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: BufferingHandler(capacity)
- Initializes the handler with a buffer of the specified capacity.
+ Initializes the handler with a buffer of the specified capacity. Here,
+ *capacity* means the number of logging records buffered.
.. method:: emit(record)
@@ -864,12 +865,13 @@ should, then :meth:`flush` is expected to do the flushing.
.. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)
Returns a new instance of the :class:`MemoryHandler` class. The instance is
- initialized with a buffer size of *capacity*. If *flushLevel* is not specified,
- :const:`ERROR` is used. If no *target* is specified, the target will need to be
- set using :meth:`setTarget` before this handler does anything useful. If
- *flushOnClose* is specified as ``False``, then the buffer is *not* flushed when
- the handler is closed. If not specified or specified as ``True``, the previous
- behaviour of flushing the buffer will occur when the handler is closed.
+ initialized with a buffer size of *capacity* (number of records buffered).
+ If *flushLevel* is not specified, :const:`ERROR` is used. If no *target* is
+ specified, the target will need to be set using :meth:`setTarget` before this
+ handler does anything useful. If *flushOnClose* is specified as ``False``,
+ then the buffer is *not* flushed when the handler is closed. If not specified
+ or specified as ``True``, the previous behaviour of flushing the buffer will
+ occur when the handler is closed.
.. versionchanged:: 3.6
The *flushOnClose* parameter was added.
From webhook-mailer at python.org Mon Jul 1 08:12:44 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 12:12:44 -0000
Subject: [Python-checkins] bpo-10945: Drop support for bdist_wininst on
non-Windows systems (GH-14506)
Message-ID:
https://github.com/python/cpython/commit/72cd653c4ed7a4f8f8fb06ac364b08a97085a2b5
commit: 72cd653c4ed7a4f8f8fb06ac364b08a97085a2b5
branch: master
author: Miro Hron?ok
committer: Victor Stinner
date: 2019-07-01T14:12:40+02:00
summary:
bpo-10945: Drop support for bdist_wininst on non-Windows systems (GH-14506)
bdist_wininst depends on MBCS codec, unavailable on non-Windows,
and bdist_wininst have not worked since at least Python 3.2, possibly
never on Python 3.
Here we document that bdist_wininst is only supported on Windows,
and we mark it unsupported otherwise to skip tests.
Distributors of Python 3 can now safely drop the bdist_wininst .exe files
without the need to skip bdist_wininst related tests.
files:
A Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
M Doc/distutils/builtdist.rst
M Lib/distutils/command/bdist_wininst.py
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index f44d0d039f45..8c65d9d59118 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -315,8 +315,8 @@ or the :command:`bdist` command with the :option:`!--formats` option::
If you have a pure module distribution (only containing pure Python modules and
packages), the resulting installer will be version independent and have a name
-like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix
-platforms or Mac OS X.
+like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary
+distributions in only supported on Windows systems.
If you have a non-pure distribution, the extensions can only be created on a
Windows platform, and will be Python version dependent. The installer filename
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 3a616883bee5..acaa184b5f71 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -55,6 +55,9 @@ class bdist_wininst(Command):
boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
'skip-build']
+ # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows
+ _unsupported = (sys.platform != "win32")
+
def initialize_options(self):
self.bdist_dir = None
self.plat_name = None
diff --git a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
new file mode 100644
index 000000000000..d39576545efa
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
@@ -0,0 +1,2 @@
+Officially drop support for creating bdist_wininst installers on non-Windows
+systems.
From webhook-mailer at python.org Mon Jul 1 08:42:16 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 12:42:16 -0000
Subject: [Python-checkins] bpo-10945: Drop support for bdist_wininst on
non-Windows systems (GH-14506)
Message-ID:
https://github.com/python/cpython/commit/45c10da40912e04c0d0de02af4b23438ed0de49b
commit: 45c10da40912e04c0d0de02af4b23438ed0de49b
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T05:42:08-07:00
summary:
bpo-10945: Drop support for bdist_wininst on non-Windows systems (GH-14506)
bdist_wininst depends on MBCS codec, unavailable on non-Windows,
and bdist_wininst have not worked since at least Python 3.2, possibly
never on Python 3.
Here we document that bdist_wininst is only supported on Windows,
and we mark it unsupported otherwise to skip tests.
Distributors of Python 3 can now safely drop the bdist_wininst .exe files
without the need to skip bdist_wininst related tests.
(cherry picked from commit 72cd653c4ed7a4f8f8fb06ac364b08a97085a2b5)
Co-authored-by: Miro Hron?ok
files:
A Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
M Doc/distutils/builtdist.rst
M Lib/distutils/command/bdist_wininst.py
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index f1f347126160..0a83f8bd6599 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -313,8 +313,8 @@ or the :command:`bdist` command with the :option:`!--formats` option::
If you have a pure module distribution (only containing pure Python modules and
packages), the resulting installer will be version independent and have a name
-like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix
-platforms or Mac OS X.
+like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary
+distributions in only supported on Windows systems.
If you have a non-pure distribution, the extensions can only be created on a
Windows platform, and will be Python version dependent. The installer filename
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index fde56754e891..15434c3a9898 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -55,6 +55,9 @@ class bdist_wininst(Command):
boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
'skip-build']
+ # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows
+ _unsupported = (sys.platform != "win32")
+
def initialize_options(self):
self.bdist_dir = None
self.plat_name = None
diff --git a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
new file mode 100644
index 000000000000..d39576545efa
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
@@ -0,0 +1,2 @@
+Officially drop support for creating bdist_wininst installers on non-Windows
+systems.
From webhook-mailer at python.org Mon Jul 1 08:54:26 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 12:54:26 -0000
Subject: [Python-checkins] bpo-10945: Drop support for bdist_wininst on
non-Windows systems (GH-14506)
Message-ID:
https://github.com/python/cpython/commit/be5bb52f5f2d4da4b9d6f42399f7275ab47910f3
commit: be5bb52f5f2d4da4b9d6f42399f7275ab47910f3
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T05:54:19-07:00
summary:
bpo-10945: Drop support for bdist_wininst on non-Windows systems (GH-14506)
bdist_wininst depends on MBCS codec, unavailable on non-Windows,
and bdist_wininst have not worked since at least Python 3.2, possibly
never on Python 3.
Here we document that bdist_wininst is only supported on Windows,
and we mark it unsupported otherwise to skip tests.
Distributors of Python 3 can now safely drop the bdist_wininst .exe files
without the need to skip bdist_wininst related tests.
(cherry picked from commit 72cd653c4ed7a4f8f8fb06ac364b08a97085a2b5)
Co-authored-by: Miro Hron?ok
files:
A Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
M Doc/distutils/builtdist.rst
M Lib/distutils/command/bdist_wininst.py
diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst
index f44d0d039f45..8c65d9d59118 100644
--- a/Doc/distutils/builtdist.rst
+++ b/Doc/distutils/builtdist.rst
@@ -315,8 +315,8 @@ or the :command:`bdist` command with the :option:`!--formats` option::
If you have a pure module distribution (only containing pure Python modules and
packages), the resulting installer will be version independent and have a name
-like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix
-platforms or Mac OS X.
+like :file:`foo-1.0.win32.exe`. Note that creating ``wininst`` binary
+distributions in only supported on Windows systems.
If you have a non-pure distribution, the extensions can only be created on a
Windows platform, and will be Python version dependent. The installer filename
diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py
index 3a616883bee5..acaa184b5f71 100644
--- a/Lib/distutils/command/bdist_wininst.py
+++ b/Lib/distutils/command/bdist_wininst.py
@@ -55,6 +55,9 @@ class bdist_wininst(Command):
boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize',
'skip-build']
+ # bpo-10945: bdist_wininst requires mbcs encoding only available on Windows
+ _unsupported = (sys.platform != "win32")
+
def initialize_options(self):
self.bdist_dir = None
self.plat_name = None
diff --git a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
new file mode 100644
index 000000000000..d39576545efa
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst
@@ -0,0 +1,2 @@
+Officially drop support for creating bdist_wininst installers on non-Windows
+systems.
From webhook-mailer at python.org Mon Jul 1 09:52:01 2019
From: webhook-mailer at python.org (Antoine Pitrou)
Date: Mon, 01 Jul 2019 13:52:01 -0000
Subject: [Python-checkins] bpo-37209: Add pickle entry for 3.8 whatsnew
(GH-14503)
Message-ID:
https://github.com/python/cpython/commit/ec6c1bd0491590f3c0e2908a7b2dfb91b6acdae9
commit: ec6c1bd0491590f3c0e2908a7b2dfb91b6acdae9
branch: master
author: Pierre Glaser
committer: Antoine Pitrou
date: 2019-07-01T15:51:57+02:00
summary:
bpo-37209: Add pickle entry for 3.8 whatsnew (GH-14503)
files:
M Doc/whatsnew/3.8.rst
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 5aab191f1a48..61e1d3da989d 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -625,6 +625,20 @@ to a path.
(Contributed by Joannah Nanjekye in :issue:`26978`)
+pickle
+------
+
+Reduction methods can now include a 6th item in the tuple they return. This
+item should specify a custom state-setting method that's called instead of the
+regular ``__setstate__`` method.
+(Contributed by Pierre Glaser and Olivier Grisel in :issue:`35900`)
+
+:mod:`pickle` extensions subclassing the C-optimized :class:`~pickle.Pickler`
+can now override the pickling logic of functions and classes by defining the
+special :meth:`~pickle.Pickler.reducer_override` method.
+(Contributed by Pierre Glaser and Olivier Grisel in :issue:`35900`)
+
+
plistlib
--------
From webhook-mailer at python.org Mon Jul 1 10:05:10 2019
From: webhook-mailer at python.org (Antoine Pitrou)
Date: Mon, 01 Jul 2019 14:05:10 -0000
Subject: [Python-checkins] bpo-37209: Add pickle entry for 3.8 whatsnew
(GH-14503) (GH-14512)
Message-ID:
https://github.com/python/cpython/commit/e224d2865aa0f021b25d68de9a6c2be617341f4c
commit: e224d2865aa0f021b25d68de9a6c2be617341f4c
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Antoine Pitrou
date: 2019-07-01T16:05:02+02:00
summary:
bpo-37209: Add pickle entry for 3.8 whatsnew (GH-14503) (GH-14512)
(cherry picked from commit ec6c1bd0491590f3c0e2908a7b2dfb91b6acdae9)
Co-authored-by: Pierre Glaser
files:
M Doc/whatsnew/3.8.rst
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index f423765c8917..1f5694caf9a4 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -622,6 +622,20 @@ to a path.
(Contributed by Joannah Nanjekye in :issue:`26978`)
+pickle
+------
+
+Reduction methods can now include a 6th item in the tuple they return. This
+item should specify a custom state-setting method that's called instead of the
+regular ``__setstate__`` method.
+(Contributed by Pierre Glaser and Olivier Grisel in :issue:`35900`)
+
+:mod:`pickle` extensions subclassing the C-optimized :class:`~pickle.Pickler`
+can now override the pickling logic of functions and classes by defining the
+special :meth:`~pickle.Pickler.reducer_override` method.
+(Contributed by Pierre Glaser and Olivier Grisel in :issue:`35900`)
+
+
plistlib
--------
From webhook-mailer at python.org Mon Jul 1 10:51:26 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 14:51:26 -0000
Subject: [Python-checkins] bpo-37467: Fix PyErr_Display() for bytes filename
(GH-14504)
Message-ID:
https://github.com/python/cpython/commit/f9b7457bd7f438263e0d2dd1f70589ad56a2585e
commit: f9b7457bd7f438263e0d2dd1f70589ad56a2585e
branch: master
author: Victor Stinner
committer: GitHub
date: 2019-07-01T16:51:18+02:00
summary:
bpo-37467: Fix PyErr_Display() for bytes filename (GH-14504)
Fix sys.excepthook() and PyErr_Display() if a filename is a bytes
string. For example, for a SyntaxError exception where the filename
attribute is a bytes string.
Cleanup also test_sys:
* Sort imports.
* Rename numruns global var to INTERN_NUMRUNS.
* Add DisplayHookTest and ExceptHookTest test case classes.
* Don't save/restore sys.stdout and sys.displayhook using
setUp()/tearDown(): do it in each test method.
* Test error case (call hook with no argument) after the success case.
files:
A Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
M Lib/test/test_sys.py
M Python/pythonrun.c
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index c223f92ba6bb..8852aaef9437 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1,81 +1,104 @@
-import unittest, test.support
+from test import support
from test.support.script_helper import assert_python_ok, assert_python_failure
-import sys, io, os
+import builtins
+import codecs
+import gc
+import io
+import locale
+import operator
+import os
import struct
import subprocess
+import sys
+import sysconfig
+import test.support
import textwrap
+import unittest
import warnings
-import operator
-import codecs
-import gc
-import sysconfig
-import locale
+
# count the number of test runs, used to create unique
# strings to intern in test_intern()
-numruns = 0
+INTERN_NUMRUNS = 0
-class SysModuleTest(unittest.TestCase):
+class DisplayHookTest(unittest.TestCase):
- def setUp(self):
- self.orig_stdout = sys.stdout
- self.orig_stderr = sys.stderr
- self.orig_displayhook = sys.displayhook
+ def test_original_displayhook(self):
+ dh = sys.__displayhook__
- def tearDown(self):
- sys.stdout = self.orig_stdout
- sys.stderr = self.orig_stderr
- sys.displayhook = self.orig_displayhook
- test.support.reap_children()
+ with support.captured_stdout() as out:
+ dh(42)
- def test_original_displayhook(self):
- import builtins
- out = io.StringIO()
- sys.stdout = out
+ self.assertEqual(out.getvalue(), "42\n")
+ self.assertEqual(builtins._, 42)
- dh = sys.__displayhook__
+ del builtins._
- self.assertRaises(TypeError, dh)
- if hasattr(builtins, "_"):
- del builtins._
+ with support.captured_stdout() as out:
+ dh(None)
- dh(None)
self.assertEqual(out.getvalue(), "")
self.assertTrue(not hasattr(builtins, "_"))
- dh(42)
- self.assertEqual(out.getvalue(), "42\n")
- self.assertEqual(builtins._, 42)
- del sys.stdout
- self.assertRaises(RuntimeError, dh, 42)
+ # sys.displayhook() requires arguments
+ self.assertRaises(TypeError, dh)
+
+ stdout = sys.stdout
+ try:
+ del sys.stdout
+ self.assertRaises(RuntimeError, dh, 42)
+ finally:
+ sys.stdout = stdout
def test_lost_displayhook(self):
- del sys.displayhook
- code = compile("42", "", "single")
- self.assertRaises(RuntimeError, eval, code)
+ displayhook = sys.displayhook
+ try:
+ del sys.displayhook
+ code = compile("42", "", "single")
+ self.assertRaises(RuntimeError, eval, code)
+ finally:
+ sys.displayhook = displayhook
def test_custom_displayhook(self):
def baddisplayhook(obj):
raise ValueError
- sys.displayhook = baddisplayhook
- code = compile("42", "", "single")
- self.assertRaises(ValueError, eval, code)
- def test_original_excepthook(self):
- err = io.StringIO()
- sys.stderr = err
+ with support.swap_attr(sys, 'displayhook', baddisplayhook):
+ code = compile("42", "", "single")
+ self.assertRaises(ValueError, eval, code)
- eh = sys.__excepthook__
- self.assertRaises(TypeError, eh)
+class ExceptHookTest(unittest.TestCase):
+
+ def test_original_excepthook(self):
try:
raise ValueError(42)
except ValueError as exc:
- eh(*sys.exc_info())
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
self.assertTrue(err.getvalue().endswith("ValueError: 42\n"))
+ self.assertRaises(TypeError, sys.__excepthook__)
+
+ def test_excepthook_bytes_filename(self):
+ # bpo-37467: sys.excepthook() must not crash if a filename
+ # is a bytes string
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', BytesWarning)
+
+ try:
+ raise SyntaxError("msg", (b"bytes_filename", 123, 0, "text"))
+ except SyntaxError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+
+ err = err.getvalue()
+ self.assertIn(""" File "b'bytes_filename'", line 123\n""", err)
+ self.assertIn(""" text\n""", err)
+ self.assertTrue(err.endswith("SyntaxError: msg\n"))
+
def test_excepthook(self):
with test.support.captured_output("stderr") as stderr:
sys.excepthook(1, '1', 1)
@@ -85,6 +108,12 @@ def test_excepthook(self):
# FIXME: testing the code for a lost or replaced excepthook in
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
+
+class SysModuleTest(unittest.TestCase):
+
+ def tearDown(self):
+ test.support.reap_children()
+
def test_exit(self):
# call with two arguments
self.assertRaises(TypeError, sys.exit, 42, 42)
@@ -492,10 +521,10 @@ def test_43581(self):
self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
def test_intern(self):
- global numruns
- numruns += 1
+ global INTERN_NUMRUNS
+ INTERN_NUMRUNS += 1
self.assertRaises(TypeError, sys.intern)
- s = "never interned before" + str(numruns)
+ s = "never interned before" + str(INTERN_NUMRUNS)
self.assertTrue(sys.intern(s) is s)
s2 = s.swapcase().swapcase()
self.assertTrue(sys.intern(s2) is s)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
new file mode 100644
index 000000000000..5e809646b4b8
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
@@ -0,0 +1,3 @@
+Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a
+bytes string. For example, for a SyntaxError exception where the filename
+attribute is a bytes string.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 8f3ee19279d9..f1d946a0b0f8 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -797,7 +797,7 @@ print_exception(PyObject *f, PyObject *value)
Py_DECREF(value);
value = message;
- line = PyUnicode_FromFormat(" File \"%U\", line %d\n",
+ line = PyUnicode_FromFormat(" File \"%S\", line %d\n",
filename, lineno);
Py_DECREF(filename);
if (line != NULL) {
From webhook-mailer at python.org Mon Jul 1 11:11:21 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 15:11:21 -0000
Subject: [Python-checkins] bpo-37467: Fix PyErr_Display() for bytes filename
(GH-14504)
Message-ID:
https://github.com/python/cpython/commit/2683ded568b24fff1139edd9127a349f432292a6
commit: 2683ded568b24fff1139edd9127a349f432292a6
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T08:11:15-07:00
summary:
bpo-37467: Fix PyErr_Display() for bytes filename (GH-14504)
Fix sys.excepthook() and PyErr_Display() if a filename is a bytes
string. For example, for a SyntaxError exception where the filename
attribute is a bytes string.
Cleanup also test_sys:
* Sort imports.
* Rename numruns global var to INTERN_NUMRUNS.
* Add DisplayHookTest and ExceptHookTest test case classes.
* Don't save/restore sys.stdout and sys.displayhook using
setUp()/tearDown(): do it in each test method.
* Test error case (call hook with no argument) after the success case.
(cherry picked from commit f9b7457bd7f438263e0d2dd1f70589ad56a2585e)
Co-authored-by: Victor Stinner
files:
A Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
M Lib/test/test_sys.py
M Python/pythonrun.c
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index a7df7a2fc8c9..96db7de4938f 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1,81 +1,104 @@
-import unittest, test.support
+from test import support
from test.support.script_helper import assert_python_ok, assert_python_failure
-import sys, io, os
+import builtins
+import codecs
+import gc
+import io
+import locale
+import operator
+import os
import struct
import subprocess
+import sys
+import sysconfig
+import test.support
import textwrap
+import unittest
import warnings
-import operator
-import codecs
-import gc
-import sysconfig
-import locale
+
# count the number of test runs, used to create unique
# strings to intern in test_intern()
-numruns = 0
+INTERN_NUMRUNS = 0
-class SysModuleTest(unittest.TestCase):
+class DisplayHookTest(unittest.TestCase):
- def setUp(self):
- self.orig_stdout = sys.stdout
- self.orig_stderr = sys.stderr
- self.orig_displayhook = sys.displayhook
+ def test_original_displayhook(self):
+ dh = sys.__displayhook__
- def tearDown(self):
- sys.stdout = self.orig_stdout
- sys.stderr = self.orig_stderr
- sys.displayhook = self.orig_displayhook
- test.support.reap_children()
+ with support.captured_stdout() as out:
+ dh(42)
- def test_original_displayhook(self):
- import builtins
- out = io.StringIO()
- sys.stdout = out
+ self.assertEqual(out.getvalue(), "42\n")
+ self.assertEqual(builtins._, 42)
- dh = sys.__displayhook__
+ del builtins._
- self.assertRaises(TypeError, dh)
- if hasattr(builtins, "_"):
- del builtins._
+ with support.captured_stdout() as out:
+ dh(None)
- dh(None)
self.assertEqual(out.getvalue(), "")
self.assertTrue(not hasattr(builtins, "_"))
- dh(42)
- self.assertEqual(out.getvalue(), "42\n")
- self.assertEqual(builtins._, 42)
- del sys.stdout
- self.assertRaises(RuntimeError, dh, 42)
+ # sys.displayhook() requires arguments
+ self.assertRaises(TypeError, dh)
+
+ stdout = sys.stdout
+ try:
+ del sys.stdout
+ self.assertRaises(RuntimeError, dh, 42)
+ finally:
+ sys.stdout = stdout
def test_lost_displayhook(self):
- del sys.displayhook
- code = compile("42", "", "single")
- self.assertRaises(RuntimeError, eval, code)
+ displayhook = sys.displayhook
+ try:
+ del sys.displayhook
+ code = compile("42", "", "single")
+ self.assertRaises(RuntimeError, eval, code)
+ finally:
+ sys.displayhook = displayhook
def test_custom_displayhook(self):
def baddisplayhook(obj):
raise ValueError
- sys.displayhook = baddisplayhook
- code = compile("42", "", "single")
- self.assertRaises(ValueError, eval, code)
- def test_original_excepthook(self):
- err = io.StringIO()
- sys.stderr = err
+ with support.swap_attr(sys, 'displayhook', baddisplayhook):
+ code = compile("42", "", "single")
+ self.assertRaises(ValueError, eval, code)
+
- eh = sys.__excepthook__
+class ExceptHookTest(unittest.TestCase):
- self.assertRaises(TypeError, eh)
+ def test_original_excepthook(self):
try:
raise ValueError(42)
except ValueError as exc:
- eh(*sys.exc_info())
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
self.assertTrue(err.getvalue().endswith("ValueError: 42\n"))
+ self.assertRaises(TypeError, sys.__excepthook__)
+
+ def test_excepthook_bytes_filename(self):
+ # bpo-37467: sys.excepthook() must not crash if a filename
+ # is a bytes string
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', BytesWarning)
+
+ try:
+ raise SyntaxError("msg", (b"bytes_filename", 123, 0, "text"))
+ except SyntaxError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+
+ err = err.getvalue()
+ self.assertIn(""" File "b'bytes_filename'", line 123\n""", err)
+ self.assertIn(""" text\n""", err)
+ self.assertTrue(err.endswith("SyntaxError: msg\n"))
+
def test_excepthook(self):
with test.support.captured_output("stderr") as stderr:
sys.excepthook(1, '1', 1)
@@ -85,6 +108,12 @@ def test_excepthook(self):
# FIXME: testing the code for a lost or replaced excepthook in
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
+
+class SysModuleTest(unittest.TestCase):
+
+ def tearDown(self):
+ test.support.reap_children()
+
def test_exit(self):
# call with two arguments
self.assertRaises(TypeError, sys.exit, 42, 42)
@@ -501,10 +530,10 @@ def test_43581(self):
self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
def test_intern(self):
- global numruns
- numruns += 1
+ global INTERN_NUMRUNS
+ INTERN_NUMRUNS += 1
self.assertRaises(TypeError, sys.intern)
- s = "never interned before" + str(numruns)
+ s = "never interned before" + str(INTERN_NUMRUNS)
self.assertTrue(sys.intern(s) is s)
s2 = s.swapcase().swapcase()
self.assertTrue(sys.intern(s2) is s)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
new file mode 100644
index 000000000000..5e809646b4b8
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
@@ -0,0 +1,3 @@
+Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a
+bytes string. For example, for a SyntaxError exception where the filename
+attribute is a bytes string.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 8f3ee19279d9..f1d946a0b0f8 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -797,7 +797,7 @@ print_exception(PyObject *f, PyObject *value)
Py_DECREF(value);
value = message;
- line = PyUnicode_FromFormat(" File \"%U\", line %d\n",
+ line = PyUnicode_FromFormat(" File \"%S\", line %d\n",
filename, lineno);
Py_DECREF(filename);
if (line != NULL) {
From webhook-mailer at python.org Mon Jul 1 11:41:50 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 15:41:50 -0000
Subject: [Python-checkins] bpo-37467: Fix PyErr_Display() for bytes filename
(GH-14504) (GH-14515)
Message-ID:
https://github.com/python/cpython/commit/8cbffc4d96d1da0fbc38da6f34f2da30c5ffd601
commit: 8cbffc4d96d1da0fbc38da6f34f2da30c5ffd601
branch: 3.7
author: Victor Stinner
committer: GitHub
date: 2019-07-01T17:41:38+02:00
summary:
bpo-37467: Fix PyErr_Display() for bytes filename (GH-14504) (GH-14515)
Fix sys.excepthook() and PyErr_Display() if a filename is a bytes
string. For example, for a SyntaxError exception where the filename
attribute is a bytes string.
Cleanup also test_sys:
* Sort imports.
* Rename numruns global var to INTERN_NUMRUNS.
* Add DisplayHookTest and ExceptHookTest test case classes.
* Don't save/restore sys.stdout and sys.displayhook using
setUp()/tearDown(): do it in each test method.
* Test error case (call hook with no argument) after the success case.
(cherry picked from commit f9b7457bd7f438263e0d2dd1f70589ad56a2585e)
files:
A Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
M Lib/test/test_sys.py
M Python/pythonrun.c
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index ef3fee13b961..84927a393f17 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1,82 +1,103 @@
-import unittest, test.support
+from test import support
from test.support.script_helper import assert_python_ok, assert_python_failure
-import sys, io, os
+import builtins
+import codecs
+import gc
+import locale
+import operator
+import os
import struct
import subprocess
+import sys
+import sysconfig
+import test.support
import textwrap
+import unittest
import warnings
-import operator
-import codecs
-import gc
-import sysconfig
-import locale
-import threading
+
# count the number of test runs, used to create unique
# strings to intern in test_intern()
-numruns = 0
+INTERN_NUMRUNS = 0
-class SysModuleTest(unittest.TestCase):
+class DisplayHookTest(unittest.TestCase):
- def setUp(self):
- self.orig_stdout = sys.stdout
- self.orig_stderr = sys.stderr
- self.orig_displayhook = sys.displayhook
+ def test_original_displayhook(self):
+ dh = sys.__displayhook__
- def tearDown(self):
- sys.stdout = self.orig_stdout
- sys.stderr = self.orig_stderr
- sys.displayhook = self.orig_displayhook
- test.support.reap_children()
+ with support.captured_stdout() as out:
+ dh(42)
- def test_original_displayhook(self):
- import builtins
- out = io.StringIO()
- sys.stdout = out
+ self.assertEqual(out.getvalue(), "42\n")
+ self.assertEqual(builtins._, 42)
- dh = sys.__displayhook__
+ del builtins._
- self.assertRaises(TypeError, dh)
- if hasattr(builtins, "_"):
- del builtins._
+ with support.captured_stdout() as out:
+ dh(None)
- dh(None)
self.assertEqual(out.getvalue(), "")
self.assertTrue(not hasattr(builtins, "_"))
- dh(42)
- self.assertEqual(out.getvalue(), "42\n")
- self.assertEqual(builtins._, 42)
- del sys.stdout
- self.assertRaises(RuntimeError, dh, 42)
+ # sys.displayhook() requires arguments
+ self.assertRaises(TypeError, dh)
+
+ stdout = sys.stdout
+ try:
+ del sys.stdout
+ self.assertRaises(RuntimeError, dh, 42)
+ finally:
+ sys.stdout = stdout
def test_lost_displayhook(self):
- del sys.displayhook
- code = compile("42", "", "single")
- self.assertRaises(RuntimeError, eval, code)
+ displayhook = sys.displayhook
+ try:
+ del sys.displayhook
+ code = compile("42", "", "single")
+ self.assertRaises(RuntimeError, eval, code)
+ finally:
+ sys.displayhook = displayhook
def test_custom_displayhook(self):
def baddisplayhook(obj):
raise ValueError
- sys.displayhook = baddisplayhook
- code = compile("42", "", "single")
- self.assertRaises(ValueError, eval, code)
- def test_original_excepthook(self):
- err = io.StringIO()
- sys.stderr = err
+ with support.swap_attr(sys, 'displayhook', baddisplayhook):
+ code = compile("42", "", "single")
+ self.assertRaises(ValueError, eval, code)
+
- eh = sys.__excepthook__
+class ExceptHookTest(unittest.TestCase):
- self.assertRaises(TypeError, eh)
+ def test_original_excepthook(self):
try:
raise ValueError(42)
except ValueError as exc:
- eh(*sys.exc_info())
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
self.assertTrue(err.getvalue().endswith("ValueError: 42\n"))
+ self.assertRaises(TypeError, sys.__excepthook__)
+
+ def test_excepthook_bytes_filename(self):
+ # bpo-37467: sys.excepthook() must not crash if a filename
+ # is a bytes string
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', BytesWarning)
+
+ try:
+ raise SyntaxError("msg", (b"bytes_filename", 123, 0, "text"))
+ except SyntaxError as exc:
+ with support.captured_stderr() as err:
+ sys.__excepthook__(*sys.exc_info())
+
+ err = err.getvalue()
+ self.assertIn(""" File "b'bytes_filename'", line 123\n""", err)
+ self.assertIn(""" text\n""", err)
+ self.assertTrue(err.endswith("SyntaxError: msg\n"))
+
def test_excepthook(self):
with test.support.captured_output("stderr") as stderr:
sys.excepthook(1, '1', 1)
@@ -86,6 +107,12 @@ def test_excepthook(self):
# FIXME: testing the code for a lost or replaced excepthook in
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
+
+class SysModuleTest(unittest.TestCase):
+
+ def tearDown(self):
+ test.support.reap_children()
+
def test_exit(self):
# call with two arguments
self.assertRaises(TypeError, sys.exit, 42, 42)
@@ -502,10 +529,10 @@ def test_43581(self):
self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
def test_intern(self):
- global numruns
- numruns += 1
+ global INTERN_NUMRUNS
+ INTERN_NUMRUNS += 1
self.assertRaises(TypeError, sys.intern)
- s = "never interned before" + str(numruns)
+ s = "never interned before" + str(INTERN_NUMRUNS)
self.assertTrue(sys.intern(s) is s)
s2 = s.swapcase().swapcase()
self.assertTrue(sys.intern(s2) is s)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
new file mode 100644
index 000000000000..5e809646b4b8
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst
@@ -0,0 +1,3 @@
+Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a
+bytes string. For example, for a SyntaxError exception where the filename
+attribute is a bytes string.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index c4ec5ac66c47..4c974cef39c7 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -750,7 +750,7 @@ print_exception(PyObject *f, PyObject *value)
Py_DECREF(value);
value = message;
- line = PyUnicode_FromFormat(" File \"%U\", line %d\n",
+ line = PyUnicode_FromFormat(" File \"%S\", line %d\n",
filename, lineno);
Py_DECREF(filename);
if (line != NULL) {
From webhook-mailer at python.org Mon Jul 1 12:28:29 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 16:28:29 -0000
Subject: [Python-checkins] Remove unused imports in tests (GH-14518)
Message-ID:
https://github.com/python/cpython/commit/8f4ef3b019ce380022018587571b0f970e668de3
commit: 8f4ef3b019ce380022018587571b0f970e668de3
branch: master
author: Victor Stinner
committer: GitHub
date: 2019-07-01T18:28:25+02:00
summary:
Remove unused imports in tests (GH-14518)
files:
M Lib/test/libregrtest/main.py
M Lib/test/support/__init__.py
M Lib/test/test__xxsubinterpreters.py
M Lib/test/test_argparse.py
M Lib/test/test_asynchat.py
M Lib/test/test_asyncio/test_events.py
M Lib/test/test_asyncio/test_pep492.py
M Lib/test/test_asyncio/test_proactor_events.py
M Lib/test/test_asyncio/test_server.py
M Lib/test/test_asyncio/test_sslproto.py
M Lib/test/test_asyncio/test_unix_events.py
M Lib/test/test_asyncio/test_windows_events.py
M Lib/test/test_audit.py
M Lib/test/test_c_locale_coercion.py
M Lib/test/test_capi.py
M Lib/test/test_cgi.py
M Lib/test/test_cmath.py
M Lib/test/test_cmd_line.py
M Lib/test/test_codeccallbacks.py
M Lib/test/test_codecs.py
M Lib/test/test_collections.py
M Lib/test/test_cprofile.py
M Lib/test/test_docxmlrpc.py
M Lib/test/test_email/test_policy.py
M Lib/test/test_embed.py
M Lib/test/test_exceptions.py
M Lib/test/test_faulthandler.py
M Lib/test/test_fork1.py
M Lib/test/test_generators.py
M Lib/test/test_gettext.py
M Lib/test/test_imaplib.py
M Lib/test/test_import/__init__.py
M Lib/test/test_importlib/test_util.py
M Lib/test/test_locale.py
M Lib/test/test_math.py
M Lib/test/test_os.py
M Lib/test/test_peepholer.py
M Lib/test/test_picklebuffer.py
M Lib/test/test_platform.py
M Lib/test/test_posixpath.py
M Lib/test/test_pyclbr.py
M Lib/test/test_pydoc.py
M Lib/test/test_runpy.py
M Lib/test/test_signal.py
M Lib/test/test_smtplib.py
M Lib/test/test_ssl.py
M Lib/test/test_string_literals.py
M Lib/test/test_subprocess.py
M Lib/test/test_sys.py
M Lib/test/test_tabnanny.py
M Lib/test/test_threaded_import.py
M Lib/test/test_threadedtempfile.py
M Lib/test/test_zipfile.py
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 1dfbe47a2fab..e2274254fdb8 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -587,7 +587,6 @@ def create_temp_dir(self):
def cleanup(self):
import glob
- import shutil
path = os.path.join(self.tmp_dir, 'test_python_*')
print("Cleanup %s directory" % self.tmp_dir)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index a65de4a5abe8..611c1cc9776d 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -6,7 +6,6 @@
import asyncio.events
import collections.abc
import contextlib
-import datetime
import errno
import faulthandler
import fnmatch
@@ -15,7 +14,6 @@
import glob
import importlib
import importlib.util
-import io
import logging.handlers
import nntplib
import os
diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py
index 1eece9659249..78b2030a1f6d 100644
--- a/Lib/test/test__xxsubinterpreters.py
+++ b/Lib/test/test__xxsubinterpreters.py
@@ -4,7 +4,7 @@
import os
import pickle
import sys
-from textwrap import dedent, indent
+from textwrap import dedent
import threading
import time
import unittest
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index bcf2cc9b26a3..9079d4bc7aa7 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1,6 +1,5 @@
# Author: Steven J. Bethard .
-import codecs
import inspect
import os
import shutil
diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py
index 1d147c741961..14c0ec43d422 100644
--- a/Lib/test/test_asynchat.py
+++ b/Lib/test/test_asynchat.py
@@ -7,7 +7,6 @@
import errno
import socket
import sys
-import _thread as thread
import threading
import time
import unittest
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 045654e87a85..e5ad72fe5ba8 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -26,8 +26,6 @@
import tty
import asyncio
-from asyncio import base_events
-from asyncio import constants
from asyncio import coroutines
from asyncio import events
from asyncio import proactor_events
diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py
index 11c0ce495d52..a5cf37ded7c9 100644
--- a/Lib/test/test_asyncio/test_pep492.py
+++ b/Lib/test/test_asyncio/test_pep492.py
@@ -4,7 +4,6 @@
import types
import unittest
-from test import support
from unittest import mock
import asyncio
diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py
index 2e9995d32807..b2fd60683c57 100644
--- a/Lib/test/test_asyncio/test_proactor_events.py
+++ b/Lib/test/test_asyncio/test_proactor_events.py
@@ -4,11 +4,9 @@
import socket
import unittest
import sys
-from collections import deque
from unittest import mock
import asyncio
-from asyncio import events
from asyncio.proactor_events import BaseProactorEventLoop
from asyncio.proactor_events import _ProactorSocketTransport
from asyncio.proactor_events import _ProactorWritePipeTransport
diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py
index 0e38e6c8ecd4..d47ccc027677 100644
--- a/Lib/test/test_asyncio/test_server.py
+++ b/Lib/test/test_asyncio/test_server.py
@@ -1,5 +1,4 @@
import asyncio
-import socket
import time
import threading
import unittest
diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py
index 1c2285063ef6..9457bc982b06 100644
--- a/Lib/test/test_asyncio/test_sslproto.py
+++ b/Lib/test/test_asyncio/test_sslproto.py
@@ -15,7 +15,6 @@
from asyncio import log
from asyncio import protocols
from asyncio import sslproto
-from asyncio import tasks
from test.test_asyncio import utils as test_utils
from test.test_asyncio import functional as func_tests
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 462a8b3c7859..1daa870a7b27 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -22,8 +22,6 @@
import asyncio
from asyncio import log
-from asyncio import base_events
-from asyncio import events
from asyncio import unix_events
from test.test_asyncio import utils as test_utils
diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py
index 1e1c01d713b5..64543268b1ef 100644
--- a/Lib/test/test_asyncio/test_windows_events.py
+++ b/Lib/test/test_asyncio/test_windows_events.py
@@ -2,7 +2,6 @@
import signal
import socket
import sys
-import subprocess
import time
import threading
import unittest
@@ -12,14 +11,12 @@
raise unittest.SkipTest('Windows only')
import _overlapped
-import _testcapi
import _winapi
import asyncio
from asyncio import windows_events
from asyncio.streams import _StreamProtocol
from test.test_asyncio import utils as test_utils
-from test.support.script_helper import spawn_python
def tearDownModule():
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index 2fc41bddcb8a..41f9fae10223 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -1,7 +1,6 @@
"""Tests for sys.audit and sys.addaudithook
"""
-import os
import subprocess
import sys
import unittest
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index 35272b5c15ac..8149e2b98bb3 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -2,7 +2,6 @@
import locale
import os
-import shutil
import subprocess
import sys
import sysconfig
@@ -10,10 +9,8 @@
from collections import namedtuple
from test import support
-from test.support.script_helper import (
- run_python_until_end,
- interpreter_requires_environment,
-)
+from test.support.script_helper import run_python_until_end
+
# Set the list of ways we expect to be able to ask for the "C" locale
EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"]
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 45fabd599159..7b35ba60b53a 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -8,7 +8,6 @@
import re
import subprocess
import sys
-import sysconfig
import textwrap
import threading
import time
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index b86638e1c283..092255598259 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -1,4 +1,3 @@
-from test.support import check_warnings
import cgi
import os
import sys
diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py
index a00185f43dbf..668f27c8a082 100644
--- a/Lib/test/test_cmath.py
+++ b/Lib/test/test_cmath.py
@@ -6,7 +6,7 @@
from cmath import phase, polar, rect, pi
import platform
import sys
-import sysconfig
+
INF = float('inf')
NAN = float('nan')
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index f7925eb795c7..497bfa9eb89d 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -5,7 +5,6 @@
import os
import subprocess
import sys
-import sysconfig
import tempfile
import unittest
from test import support
diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py
index 585992be1f0b..243f002c4eca 100644
--- a/Lib/test/test_codeccallbacks.py
+++ b/Lib/test/test_codeccallbacks.py
@@ -1,10 +1,10 @@
import codecs
import html.entities
import sys
-import test.support
import unicodedata
import unittest
+
class PosReturn:
# this can be used for configurable callbacks
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 4317dfceb039..b187ca650dc6 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -29,7 +29,7 @@ def check(input, expect):
# On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present
def is_code_page_present(cp):
- from ctypes import POINTER, WINFUNCTYPE, windll, WinError, Structure, WinDLL
+ from ctypes import POINTER, WINFUNCTYPE, WinDLL
from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD
MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term.
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index e2d04d5b4761..e532be6eeaf0 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -13,7 +13,7 @@
import types
import unittest
-from collections import namedtuple, Counter, OrderedDict, _count_elements, _tuplegetter
+from collections import namedtuple, Counter, OrderedDict, _count_elements
from collections import UserDict, UserString, UserList
from collections import ChainMap
from collections import deque
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 5c70037f39a2..4ec769885292 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -6,7 +6,7 @@
# rip off all interesting stuff from test_profile
import cProfile
from test.test_profile import ProfileTest, regenerate_expected_output
-from test.support.script_helper import assert_python_failure, assert_python_ok
+from test.support.script_helper import assert_python_failure
from test import support
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
index f077f05f5b4f..116e626740df 100644
--- a/Lib/test/test_docxmlrpc.py
+++ b/Lib/test/test_docxmlrpc.py
@@ -2,7 +2,6 @@
import http.client
import sys
import threading
-from test import support
import unittest
def make_request_and_skipIf(condition, reason):
diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py
index 0aea934df434..1e39aa062c0a 100644
--- a/Lib/test/test_email/test_policy.py
+++ b/Lib/test/test_email/test_policy.py
@@ -1,5 +1,4 @@
import io
-import sys
import types
import textwrap
import unittest
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 9c78aa059fc3..e1cf4be50668 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -5,7 +5,6 @@
from collections import namedtuple
import json
import os
-import platform
import re
import subprocess
import sys
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index d7e11d2d30a8..10c1e076464e 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -9,7 +9,7 @@
import errno
from test.support import (TESTFN, captured_stderr, check_impl_detail,
- check_warnings, cpython_only, gc_collect, run_unittest,
+ check_warnings, cpython_only, gc_collect,
no_tracing, unlink, import_module, script_helper,
SuppressCrashReport)
from test import support
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index f0be91844ffa..1cf20db1c7ff 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -9,7 +9,6 @@
from test import support
from test.support import script_helper, is_android
import tempfile
-import threading
import unittest
from textwrap import dedent
diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py
index 9ca9724c4c91..2ab856ff5690 100644
--- a/Lib/test/test_fork1.py
+++ b/Lib/test/test_fork1.py
@@ -10,8 +10,7 @@
import unittest
from test.fork_wait import ForkWait
-from test.support import (reap_children, get_attribute,
- import_module, verbose)
+from test.support import reap_children, get_attribute, verbose
# Skip test if fork does not exist.
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index a34e4ec2eda7..f8d86da5e2f5 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -3,7 +3,6 @@
import pickle
import sys
import unittest
-import warnings
import weakref
import inspect
diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py
index 9d1a96b8b0d1..baf300b05724 100644
--- a/Lib/test/test_gettext.py
+++ b/Lib/test/test_gettext.py
@@ -2,7 +2,6 @@
import base64
import contextlib
import gettext
-import locale
import unittest
from test import support
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 9305e47ee993..8ab532af3f0d 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -1,7 +1,6 @@
from test import support
from contextlib import contextmanager
-import errno
import imaplib
import os.path
import socketserver
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 84cd0da94b36..50406d9aa1d9 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -5,7 +5,6 @@
import builtins
import marshal
import os
-import platform
import py_compile
import random
import shutil
@@ -23,9 +22,9 @@
import test.support
from test.support import (
- EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
- make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask,
- unlink, unload, create_empty_file, cpython_only, TESTFN_UNENCODABLE,
+ TESTFN, forget, is_jython,
+ make_legacy_pyc, rmtree, swap_attr, swap_item, temp_umask,
+ unlink, unload, cpython_only, TESTFN_UNENCODABLE,
temp_dir, DirsOnSysPath)
from test.support import script_helper
from test.test_importlib.util import uncache
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index db0899aff6b9..0350a5a5cc05 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -4,7 +4,6 @@
machinery = util.import_importlib('importlib.machinery')
importlib_util = util.import_importlib('importlib.util')
-import contextlib
import importlib.util
import os
import pathlib
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
index e2c2178ae6cc..792a15c50f92 100644
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -3,7 +3,7 @@
import locale
import sys
import codecs
-import warnings
+
class BaseLocalizedTest(unittest.TestCase):
#
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index 362d09370d45..393cdaff1818 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -12,7 +12,7 @@
import random
import struct
import sys
-import sysconfig
+
eps = 1E-05
NAN = float('nan')
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 784000a2eb36..b2cd4cca5f21 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -9,7 +9,6 @@
import decimal
import errno
import fractions
-import getpass
import itertools
import locale
import mmap
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index b5f85bd55973..c90a53210a93 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -1,10 +1,9 @@
import dis
import unittest
-import types
-import textwrap
from test.bytecode_helper import BytecodeTestCase
+
def count_instr_recursively(f, opname):
count = 0
for instr in dis.get_instructions(f):
diff --git a/Lib/test/test_picklebuffer.py b/Lib/test/test_picklebuffer.py
index 7e72157fd022..97981c882e82 100644
--- a/Lib/test/test_picklebuffer.py
+++ b/Lib/test/test_picklebuffer.py
@@ -5,7 +5,6 @@
import gc
from pickle import PickleBuffer
-import sys
import weakref
import unittest
diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py
index 8b64923e174c..3084663a8fad 100644
--- a/Lib/test/test_platform.py
+++ b/Lib/test/test_platform.py
@@ -2,13 +2,12 @@
import platform
import subprocess
import sys
-import sysconfig
-import tempfile
import unittest
from unittest import mock
from test import support
+
class PlatformTest(unittest.TestCase):
def clear_caches(self):
platform._platform_cache.clear()
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index 983e2dd6ff27..4d3d8976d604 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -1,7 +1,6 @@
import os
import posixpath
import unittest
-import warnings
from posixpath import realpath, abspath, dirname, basename
from test import support, test_genericpath
from test.support import FakePath
@@ -12,6 +11,7 @@
except ImportError:
posix = None
+
# An absolute path to a temporary filename for testing. We can't rely on TESTFN
# being an absolute path, so we need this.
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 531304021312..4385271cd0f2 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -3,15 +3,13 @@
Nick Mathewson
'''
-import os
import sys
from textwrap import dedent
from types import FunctionType, MethodType, BuiltinFunctionType
import pyclbr
from unittest import TestCase, main as unittest_main
-from test import support
from test.test_importlib import util as test_importlib_util
-from functools import partial
+
StaticMethodType = type(staticmethod(lambda: None))
ClassMethodType = type(classmethod(lambda c: None))
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 6efdeb047c21..c80477c50f09 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -21,7 +21,6 @@
import xml.etree
import xml.etree.ElementTree
import textwrap
-import threading
from io import StringIO
from collections import namedtuple
from test.support.script_helper import assert_python_ok
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index 800b483b7e15..f00308611163 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -11,8 +11,7 @@
from test.support import (
forget, make_legacy_pyc, unload, verbose, no_tracing,
create_empty_file, temp_dir)
-from test.support.script_helper import (
- make_pkg, make_script, make_zip_pkg, make_zip_script)
+from test.support.script_helper import make_script, make_zip_script
import runpy
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 063b35ca230f..d41e94b07f43 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -6,7 +6,6 @@
import statistics
import subprocess
import sys
-import threading
import time
import unittest
from test import support
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index fdcf6f219256..f1332e9ef782 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -19,7 +19,7 @@
import unittest
from test import support, mock_socket
-from test.support import HOST, HOSTv4, HOSTv6
+from test.support import HOST
from test.support import threading_setup, threading_cleanup, join_thread
from unittest.mock import Mock
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index d83ee2cc974d..ef1723903a15 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -26,7 +26,7 @@
ssl = support.import_module("ssl")
-from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
+from ssl import TLSVersion, _TLSContentType, _TLSMessageType
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
Py_DEBUG_WIN32 = Py_DEBUG and sys.platform == 'win32'
@@ -4601,7 +4601,6 @@ def msg_cb(conn, direction, version, content_type, msg_type, data):
def test_main(verbose=False):
if support.verbose:
- import warnings
plats = {
'Mac': platform.mac_ver,
'Windows': platform.win32_ver,
diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py
index 048f40d90a4b..5961d591c448 100644
--- a/Lib/test/test_string_literals.py
+++ b/Lib/test/test_string_literals.py
@@ -31,7 +31,6 @@
import sys
import shutil
import tempfile
-import warnings
import unittest
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 6b8acb258ee3..e58d0925df3b 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -3,7 +3,6 @@
from test import support
import subprocess
import sys
-import platform
import signal
import io
import itertools
@@ -20,18 +19,12 @@
import textwrap
from test.support import FakePath
-try:
- import ctypes
-except ImportError:
- ctypes = None
-else:
- import ctypes.util
-
try:
import _testcapi
except ImportError:
_testcapi = None
+
if support.PGO:
raise unittest.SkipTest("test is not helpful for PGO")
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 8852aaef9437..9961dee754c6 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -3,7 +3,6 @@
import builtins
import codecs
import gc
-import io
import locale
import operator
import os
diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py
index 81549d14ae2b..95840d6ac0c5 100644
--- a/Lib/test/test_tabnanny.py
+++ b/Lib/test/test_tabnanny.py
@@ -7,7 +7,6 @@
from unittest import mock
import errno
import os
-import sys
import tabnanny
import tokenize
import tempfile
diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py
index 035344be4b89..8607f363db21 100644
--- a/Lib/test/test_threaded_import.py
+++ b/Lib/test/test_threaded_import.py
@@ -15,7 +15,7 @@
import unittest
from unittest import mock
from test.support import (
- verbose, import_module, run_unittest, TESTFN, reap_threads,
+ verbose, run_unittest, TESTFN, reap_threads,
forget, unlink, rmtree, start_threads)
def task(N, done, done_tasks, errors):
diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py
index f3d4ba36377d..e1d7a10179cc 100644
--- a/Lib/test/test_threadedtempfile.py
+++ b/Lib/test/test_threadedtempfile.py
@@ -13,19 +13,22 @@
provoking a 2.0 failure under Linux.
"""
-NUM_THREADS = 20
-FILES_PER_THREAD = 50
-
import tempfile
-from test.support import start_threads, import_module
+from test.support import start_threads
import unittest
import io
import threading
from traceback import print_exc
+
+NUM_THREADS = 20
+FILES_PER_THREAD = 50
+
+
startEvent = threading.Event()
+
class TempFileGreedy(threading.Thread):
error_count = 0
ok_count = 0
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index bf5bb4d0f13e..19b550f80187 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -4,9 +4,7 @@
import os
import pathlib
import posixpath
-import shutil
import struct
-import tempfile
import time
import unittest
import zipfile
From webhook-mailer at python.org Mon Jul 1 12:30:52 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 16:30:52 -0000
Subject: [Python-checkins] bpo-36168: Lowercase the word "subsequent" in
get_value doc (GH-14485)
Message-ID:
https://github.com/python/cpython/commit/59ec9ee4d7f3c2444efb989e96f5124e1c246de5
commit: 59ec9ee4d7f3c2444efb989e96f5124e1c246de5
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T09:30:48-07:00
summary:
bpo-36168: Lowercase the word "subsequent" in get_value doc (GH-14485)
Subsequent -> subsequent
https://bugs.python.org/issue36168
(cherry picked from commit 12b436e3b079fb3e3a7197c089df90a77e3bdd77)
Co-authored-by: Krishna Oza
files:
M Doc/library/string.rst
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 288dde6b3fe4..af8b9b358cc3 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -146,7 +146,7 @@ implementation as the built-in :meth:`~str.format` method.
keyword arguments.
For compound field names, these functions are only called for the first
- component of the field name; Subsequent components are handled through
+ component of the field name; subsequent components are handled through
normal attribute and indexing operations.
So for example, the field expression '0.name' would cause
From webhook-mailer at python.org Mon Jul 1 12:35:13 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 16:35:13 -0000
Subject: [Python-checkins] bpo-37472: Remove Lib/test/outstanding_bugs.py
(GH-14516)
Message-ID:
https://github.com/python/cpython/commit/e21b45a8e71d06a6a03f99261cab33e72b896bb9
commit: e21b45a8e71d06a6a03f99261cab33e72b896bb9
branch: master
author: Victor Stinner
committer: GitHub
date: 2019-07-01T18:35:07+02:00
summary:
bpo-37472: Remove Lib/test/outstanding_bugs.py (GH-14516)
files:
A Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst
D Lib/test/outstanding_bugs.py
M PCbuild/lib.pyproj
diff --git a/Lib/test/outstanding_bugs.py b/Lib/test/outstanding_bugs.py
deleted file mode 100644
index 7e527a670643..000000000000
--- a/Lib/test/outstanding_bugs.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# This file is for everybody to add tests for bugs that aren't
-# fixed yet. Please add a test case and appropriate bug description.
-#
-# When you fix one of the bugs, please move the test to the correct
-# test_ module.
-#
-
-import unittest
-from test import support
-
-#
-# No test cases for outstanding bugs at the moment.
-#
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst b/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst
new file mode 100644
index 000000000000..f62b5d54867f
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst
@@ -0,0 +1 @@
+Remove ``Lib/test/outstanding_bugs.py``.
diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj
index 683335e04489..0ddeef3eaa3b 100644
--- a/PCbuild/lib.pyproj
+++ b/PCbuild/lib.pyproj
@@ -830,7 +830,6 @@
-
From webhook-mailer at python.org Mon Jul 1 13:01:57 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 17:01:57 -0000
Subject: [Python-checkins] Remove unused imports in tests (GH-14518)
(GH-14520)
Message-ID:
https://github.com/python/cpython/commit/466e18e8c2738b06a24915cb186d954821d0414f
commit: 466e18e8c2738b06a24915cb186d954821d0414f
branch: 3.8
author: Victor Stinner
committer: GitHub
date: 2019-07-01T19:01:52+02:00
summary:
Remove unused imports in tests (GH-14518) (GH-14520)
(cherry picked from commit 8f4ef3b019ce380022018587571b0f970e668de3)
files:
M Lib/test/libregrtest/main.py
M Lib/test/support/__init__.py
M Lib/test/test__xxsubinterpreters.py
M Lib/test/test_argparse.py
M Lib/test/test_asynchat.py
M Lib/test/test_asyncio/test_events.py
M Lib/test/test_asyncio/test_pep492.py
M Lib/test/test_asyncio/test_proactor_events.py
M Lib/test/test_asyncio/test_server.py
M Lib/test/test_asyncio/test_sslproto.py
M Lib/test/test_asyncio/test_unix_events.py
M Lib/test/test_asyncio/test_windows_events.py
M Lib/test/test_audit.py
M Lib/test/test_c_locale_coercion.py
M Lib/test/test_capi.py
M Lib/test/test_cgi.py
M Lib/test/test_cmath.py
M Lib/test/test_cmd_line.py
M Lib/test/test_codeccallbacks.py
M Lib/test/test_codecs.py
M Lib/test/test_collections.py
M Lib/test/test_cprofile.py
M Lib/test/test_docxmlrpc.py
M Lib/test/test_email/test_policy.py
M Lib/test/test_embed.py
M Lib/test/test_exceptions.py
M Lib/test/test_faulthandler.py
M Lib/test/test_fork1.py
M Lib/test/test_generators.py
M Lib/test/test_gettext.py
M Lib/test/test_imaplib.py
M Lib/test/test_import/__init__.py
M Lib/test/test_importlib/test_util.py
M Lib/test/test_locale.py
M Lib/test/test_math.py
M Lib/test/test_os.py
M Lib/test/test_peepholer.py
M Lib/test/test_picklebuffer.py
M Lib/test/test_platform.py
M Lib/test/test_posixpath.py
M Lib/test/test_pyclbr.py
M Lib/test/test_pydoc.py
M Lib/test/test_runpy.py
M Lib/test/test_signal.py
M Lib/test/test_smtplib.py
M Lib/test/test_ssl.py
M Lib/test/test_string_literals.py
M Lib/test/test_subprocess.py
M Lib/test/test_sys.py
M Lib/test/test_tabnanny.py
M Lib/test/test_threaded_import.py
M Lib/test/test_threadedtempfile.py
M Lib/test/test_zipfile.py
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 1dfbe47a2fab..e2274254fdb8 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -587,7 +587,6 @@ def create_temp_dir(self):
def cleanup(self):
import glob
- import shutil
path = os.path.join(self.tmp_dir, 'test_python_*')
print("Cleanup %s directory" % self.tmp_dir)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 31b0dc8fc2ca..1c91fc434eec 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -6,7 +6,6 @@
import asyncio.events
import collections.abc
import contextlib
-import datetime
import errno
import faulthandler
import fnmatch
@@ -15,7 +14,6 @@
import glob
import importlib
import importlib.util
-import io
import logging.handlers
import nntplib
import os
diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py
index 1eece9659249..78b2030a1f6d 100644
--- a/Lib/test/test__xxsubinterpreters.py
+++ b/Lib/test/test__xxsubinterpreters.py
@@ -4,7 +4,7 @@
import os
import pickle
import sys
-from textwrap import dedent, indent
+from textwrap import dedent
import threading
import time
import unittest
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index bcf2cc9b26a3..9079d4bc7aa7 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1,6 +1,5 @@
# Author: Steven J. Bethard .
-import codecs
import inspect
import os
import shutil
diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py
index 1d147c741961..14c0ec43d422 100644
--- a/Lib/test/test_asynchat.py
+++ b/Lib/test/test_asynchat.py
@@ -7,7 +7,6 @@
import errno
import socket
import sys
-import _thread as thread
import threading
import time
import unittest
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 045654e87a85..e5ad72fe5ba8 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -26,8 +26,6 @@
import tty
import asyncio
-from asyncio import base_events
-from asyncio import constants
from asyncio import coroutines
from asyncio import events
from asyncio import proactor_events
diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py
index 11c0ce495d52..a5cf37ded7c9 100644
--- a/Lib/test/test_asyncio/test_pep492.py
+++ b/Lib/test/test_asyncio/test_pep492.py
@@ -4,7 +4,6 @@
import types
import unittest
-from test import support
from unittest import mock
import asyncio
diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py
index 2e9995d32807..b2fd60683c57 100644
--- a/Lib/test/test_asyncio/test_proactor_events.py
+++ b/Lib/test/test_asyncio/test_proactor_events.py
@@ -4,11 +4,9 @@
import socket
import unittest
import sys
-from collections import deque
from unittest import mock
import asyncio
-from asyncio import events
from asyncio.proactor_events import BaseProactorEventLoop
from asyncio.proactor_events import _ProactorSocketTransport
from asyncio.proactor_events import _ProactorWritePipeTransport
diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py
index 0e38e6c8ecd4..d47ccc027677 100644
--- a/Lib/test/test_asyncio/test_server.py
+++ b/Lib/test/test_asyncio/test_server.py
@@ -1,5 +1,4 @@
import asyncio
-import socket
import time
import threading
import unittest
diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py
index 1c2285063ef6..9457bc982b06 100644
--- a/Lib/test/test_asyncio/test_sslproto.py
+++ b/Lib/test/test_asyncio/test_sslproto.py
@@ -15,7 +15,6 @@
from asyncio import log
from asyncio import protocols
from asyncio import sslproto
-from asyncio import tasks
from test.test_asyncio import utils as test_utils
from test.test_asyncio import functional as func_tests
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index 462a8b3c7859..1daa870a7b27 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -22,8 +22,6 @@
import asyncio
from asyncio import log
-from asyncio import base_events
-from asyncio import events
from asyncio import unix_events
from test.test_asyncio import utils as test_utils
diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py
index 1e1c01d713b5..64543268b1ef 100644
--- a/Lib/test/test_asyncio/test_windows_events.py
+++ b/Lib/test/test_asyncio/test_windows_events.py
@@ -2,7 +2,6 @@
import signal
import socket
import sys
-import subprocess
import time
import threading
import unittest
@@ -12,14 +11,12 @@
raise unittest.SkipTest('Windows only')
import _overlapped
-import _testcapi
import _winapi
import asyncio
from asyncio import windows_events
from asyncio.streams import _StreamProtocol
from test.test_asyncio import utils as test_utils
-from test.support.script_helper import spawn_python
def tearDownModule():
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index 2fc41bddcb8a..41f9fae10223 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -1,7 +1,6 @@
"""Tests for sys.audit and sys.addaudithook
"""
-import os
import subprocess
import sys
import unittest
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index 35272b5c15ac..8149e2b98bb3 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -2,7 +2,6 @@
import locale
import os
-import shutil
import subprocess
import sys
import sysconfig
@@ -10,10 +9,8 @@
from collections import namedtuple
from test import support
-from test.support.script_helper import (
- run_python_until_end,
- interpreter_requires_environment,
-)
+from test.support.script_helper import run_python_until_end
+
# Set the list of ways we expect to be able to ask for the "C" locale
EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"]
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 45fabd599159..7b35ba60b53a 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -8,7 +8,6 @@
import re
import subprocess
import sys
-import sysconfig
import textwrap
import threading
import time
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index b86638e1c283..092255598259 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -1,4 +1,3 @@
-from test.support import check_warnings
import cgi
import os
import sys
diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py
index a00185f43dbf..668f27c8a082 100644
--- a/Lib/test/test_cmath.py
+++ b/Lib/test/test_cmath.py
@@ -6,7 +6,7 @@
from cmath import phase, polar, rect, pi
import platform
import sys
-import sysconfig
+
INF = float('inf')
NAN = float('nan')
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index f7925eb795c7..497bfa9eb89d 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -5,7 +5,6 @@
import os
import subprocess
import sys
-import sysconfig
import tempfile
import unittest
from test import support
diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py
index 585992be1f0b..243f002c4eca 100644
--- a/Lib/test/test_codeccallbacks.py
+++ b/Lib/test/test_codeccallbacks.py
@@ -1,10 +1,10 @@
import codecs
import html.entities
import sys
-import test.support
import unicodedata
import unittest
+
class PosReturn:
# this can be used for configurable callbacks
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 4317dfceb039..b187ca650dc6 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -29,7 +29,7 @@ def check(input, expect):
# On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present
def is_code_page_present(cp):
- from ctypes import POINTER, WINFUNCTYPE, windll, WinError, Structure, WinDLL
+ from ctypes import POINTER, WINFUNCTYPE, WinDLL
from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD
MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term.
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index e2d04d5b4761..e532be6eeaf0 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -13,7 +13,7 @@
import types
import unittest
-from collections import namedtuple, Counter, OrderedDict, _count_elements, _tuplegetter
+from collections import namedtuple, Counter, OrderedDict, _count_elements
from collections import UserDict, UserString, UserList
from collections import ChainMap
from collections import deque
diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py
index 5c70037f39a2..4ec769885292 100644
--- a/Lib/test/test_cprofile.py
+++ b/Lib/test/test_cprofile.py
@@ -6,7 +6,7 @@
# rip off all interesting stuff from test_profile
import cProfile
from test.test_profile import ProfileTest, regenerate_expected_output
-from test.support.script_helper import assert_python_failure, assert_python_ok
+from test.support.script_helper import assert_python_failure
from test import support
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
index f077f05f5b4f..116e626740df 100644
--- a/Lib/test/test_docxmlrpc.py
+++ b/Lib/test/test_docxmlrpc.py
@@ -2,7 +2,6 @@
import http.client
import sys
import threading
-from test import support
import unittest
def make_request_and_skipIf(condition, reason):
diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py
index 0aea934df434..1e39aa062c0a 100644
--- a/Lib/test/test_email/test_policy.py
+++ b/Lib/test/test_email/test_policy.py
@@ -1,5 +1,4 @@
import io
-import sys
import types
import textwrap
import unittest
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index 5a90b9f6f247..ed1100cfabc5 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -5,7 +5,6 @@
from collections import namedtuple
import json
import os
-import platform
import re
import subprocess
import sys
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index d7e11d2d30a8..10c1e076464e 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -9,7 +9,7 @@
import errno
from test.support import (TESTFN, captured_stderr, check_impl_detail,
- check_warnings, cpython_only, gc_collect, run_unittest,
+ check_warnings, cpython_only, gc_collect,
no_tracing, unlink, import_module, script_helper,
SuppressCrashReport)
from test import support
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index f0be91844ffa..1cf20db1c7ff 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -9,7 +9,6 @@
from test import support
from test.support import script_helper, is_android
import tempfile
-import threading
import unittest
from textwrap import dedent
diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py
index 9ca9724c4c91..2ab856ff5690 100644
--- a/Lib/test/test_fork1.py
+++ b/Lib/test/test_fork1.py
@@ -10,8 +10,7 @@
import unittest
from test.fork_wait import ForkWait
-from test.support import (reap_children, get_attribute,
- import_module, verbose)
+from test.support import reap_children, get_attribute, verbose
# Skip test if fork does not exist.
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index a34e4ec2eda7..f8d86da5e2f5 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -3,7 +3,6 @@
import pickle
import sys
import unittest
-import warnings
import weakref
import inspect
diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py
index 9d1a96b8b0d1..baf300b05724 100644
--- a/Lib/test/test_gettext.py
+++ b/Lib/test/test_gettext.py
@@ -2,7 +2,6 @@
import base64
import contextlib
import gettext
-import locale
import unittest
from test import support
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 9305e47ee993..8ab532af3f0d 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -1,7 +1,6 @@
from test import support
from contextlib import contextmanager
-import errno
import imaplib
import os.path
import socketserver
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 84cd0da94b36..50406d9aa1d9 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -5,7 +5,6 @@
import builtins
import marshal
import os
-import platform
import py_compile
import random
import shutil
@@ -23,9 +22,9 @@
import test.support
from test.support import (
- EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
- make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask,
- unlink, unload, create_empty_file, cpython_only, TESTFN_UNENCODABLE,
+ TESTFN, forget, is_jython,
+ make_legacy_pyc, rmtree, swap_attr, swap_item, temp_umask,
+ unlink, unload, cpython_only, TESTFN_UNENCODABLE,
temp_dir, DirsOnSysPath)
from test.support import script_helper
from test.test_importlib.util import uncache
diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py
index db0899aff6b9..0350a5a5cc05 100644
--- a/Lib/test/test_importlib/test_util.py
+++ b/Lib/test/test_importlib/test_util.py
@@ -4,7 +4,6 @@
machinery = util.import_importlib('importlib.machinery')
importlib_util = util.import_importlib('importlib.util')
-import contextlib
import importlib.util
import os
import pathlib
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
index e2c2178ae6cc..792a15c50f92 100644
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -3,7 +3,7 @@
import locale
import sys
import codecs
-import warnings
+
class BaseLocalizedTest(unittest.TestCase):
#
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index b7dac5eeef63..96af655061f6 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -12,7 +12,7 @@
import random
import struct
import sys
-import sysconfig
+
eps = 1E-05
NAN = float('nan')
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 784000a2eb36..b2cd4cca5f21 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -9,7 +9,6 @@
import decimal
import errno
import fractions
-import getpass
import itertools
import locale
import mmap
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 5d00240e2595..9c206d1d09c0 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -1,10 +1,9 @@
import dis
import unittest
-import types
-import textwrap
from test.bytecode_helper import BytecodeTestCase
+
def count_instr_recursively(f, opname):
count = 0
for instr in dis.get_instructions(f):
diff --git a/Lib/test/test_picklebuffer.py b/Lib/test/test_picklebuffer.py
index 7e72157fd022..97981c882e82 100644
--- a/Lib/test/test_picklebuffer.py
+++ b/Lib/test/test_picklebuffer.py
@@ -5,7 +5,6 @@
import gc
from pickle import PickleBuffer
-import sys
import weakref
import unittest
diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py
index 8b64923e174c..3084663a8fad 100644
--- a/Lib/test/test_platform.py
+++ b/Lib/test/test_platform.py
@@ -2,13 +2,12 @@
import platform
import subprocess
import sys
-import sysconfig
-import tempfile
import unittest
from unittest import mock
from test import support
+
class PlatformTest(unittest.TestCase):
def clear_caches(self):
platform._platform_cache.clear()
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index 983e2dd6ff27..4d3d8976d604 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -1,7 +1,6 @@
import os
import posixpath
import unittest
-import warnings
from posixpath import realpath, abspath, dirname, basename
from test import support, test_genericpath
from test.support import FakePath
@@ -12,6 +11,7 @@
except ImportError:
posix = None
+
# An absolute path to a temporary filename for testing. We can't rely on TESTFN
# being an absolute path, so we need this.
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 0b3934f6226e..fafe17ce5f1b 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -3,15 +3,13 @@
Nick Mathewson
'''
-import os
import sys
from textwrap import dedent
from types import FunctionType, MethodType, BuiltinFunctionType
import pyclbr
from unittest import TestCase, main as unittest_main
-from test import support
from test.test_importlib import util as test_importlib_util
-from functools import partial
+
StaticMethodType = type(staticmethod(lambda: None))
ClassMethodType = type(classmethod(lambda c: None))
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 6efdeb047c21..c80477c50f09 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -21,7 +21,6 @@
import xml.etree
import xml.etree.ElementTree
import textwrap
-import threading
from io import StringIO
from collections import namedtuple
from test.support.script_helper import assert_python_ok
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index 800b483b7e15..f00308611163 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -11,8 +11,7 @@
from test.support import (
forget, make_legacy_pyc, unload, verbose, no_tracing,
create_empty_file, temp_dir)
-from test.support.script_helper import (
- make_pkg, make_script, make_zip_pkg, make_zip_script)
+from test.support.script_helper import make_script, make_zip_script
import runpy
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 063b35ca230f..d41e94b07f43 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -6,7 +6,6 @@
import statistics
import subprocess
import sys
-import threading
import time
import unittest
from test import support
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index fdcf6f219256..f1332e9ef782 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -19,7 +19,7 @@
import unittest
from test import support, mock_socket
-from test.support import HOST, HOSTv4, HOSTv6
+from test.support import HOST
from test.support import threading_setup, threading_cleanup, join_thread
from unittest.mock import Mock
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 66369fe60dfe..1898990fb796 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -26,7 +26,7 @@
ssl = support.import_module("ssl")
-from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType
+from ssl import TLSVersion, _TLSContentType, _TLSMessageType
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
HOST = support.HOST
@@ -4592,7 +4592,6 @@ def msg_cb(conn, direction, version, content_type, msg_type, data):
def test_main(verbose=False):
if support.verbose:
- import warnings
plats = {
'Mac': platform.mac_ver,
'Windows': platform.win32_ver,
diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py
index 048f40d90a4b..5961d591c448 100644
--- a/Lib/test/test_string_literals.py
+++ b/Lib/test/test_string_literals.py
@@ -31,7 +31,6 @@
import sys
import shutil
import tempfile
-import warnings
import unittest
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 97d21904b9ce..9bfc21123cc0 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -3,7 +3,6 @@
from test import support
import subprocess
import sys
-import platform
import signal
import io
import itertools
@@ -20,18 +19,12 @@
import textwrap
from test.support import FakePath
-try:
- import ctypes
-except ImportError:
- ctypes = None
-else:
- import ctypes.util
-
try:
import _testcapi
except ImportError:
_testcapi = None
+
if support.PGO:
raise unittest.SkipTest("test is not helpful for PGO")
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 96db7de4938f..af0e54bd0e23 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -3,7 +3,6 @@
import builtins
import codecs
import gc
-import io
import locale
import operator
import os
diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py
index 81549d14ae2b..95840d6ac0c5 100644
--- a/Lib/test/test_tabnanny.py
+++ b/Lib/test/test_tabnanny.py
@@ -7,7 +7,6 @@
from unittest import mock
import errno
import os
-import sys
import tabnanny
import tokenize
import tempfile
diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py
index 035344be4b89..8607f363db21 100644
--- a/Lib/test/test_threaded_import.py
+++ b/Lib/test/test_threaded_import.py
@@ -15,7 +15,7 @@
import unittest
from unittest import mock
from test.support import (
- verbose, import_module, run_unittest, TESTFN, reap_threads,
+ verbose, run_unittest, TESTFN, reap_threads,
forget, unlink, rmtree, start_threads)
def task(N, done, done_tasks, errors):
diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py
index f3d4ba36377d..e1d7a10179cc 100644
--- a/Lib/test/test_threadedtempfile.py
+++ b/Lib/test/test_threadedtempfile.py
@@ -13,19 +13,22 @@
provoking a 2.0 failure under Linux.
"""
-NUM_THREADS = 20
-FILES_PER_THREAD = 50
-
import tempfile
-from test.support import start_threads, import_module
+from test.support import start_threads
import unittest
import io
import threading
from traceback import print_exc
+
+NUM_THREADS = 20
+FILES_PER_THREAD = 50
+
+
startEvent = threading.Event()
+
class TempFileGreedy(threading.Thread):
error_count = 0
ok_count = 0
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index bf5bb4d0f13e..19b550f80187 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -4,9 +4,7 @@
import os
import pathlib
import posixpath
-import shutil
import struct
-import tempfile
import time
import unittest
import zipfile
From webhook-mailer at python.org Mon Jul 1 13:13:54 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 17:13:54 -0000
Subject: [Python-checkins] bpo-36763: Add PyConfig_SetWideStringList()
(GH-14444)
Message-ID:
https://github.com/python/cpython/commit/36242fd871d0f0977e720d4fae5700774bd8c09a
commit: 36242fd871d0f0977e720d4fae5700774bd8c09a
branch: master
author: Victor Stinner
committer: GitHub
date: 2019-07-01T19:13:50+02:00
summary:
bpo-36763: Add PyConfig_SetWideStringList() (GH-14444)
files:
A Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
M Doc/c-api/init_config.rst
M Include/cpython/initconfig.h
M Python/initconfig.c
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 0d94e6b8f27b..d2c1f9a2f3e3 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -25,6 +25,7 @@ Functions:
* :c:func:`PyConfig_SetBytesArgv`
* :c:func:`PyConfig_SetBytesString`
* :c:func:`PyConfig_SetString`
+* :c:func:`PyConfig_SetWideStringList`
* :c:func:`PyPreConfig_InitIsolatedConfig`
* :c:func:`PyPreConfig_InitPythonConfig`
* :c:func:`PyStatus_Error`
@@ -368,6 +369,12 @@ PyConfig
Preinitialize Python if needed.
+ .. c:function:: PyStatus PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)
+
+ Set the list of wide strings *list* to *length* and *items*.
+
+ Preinitialize Python if needed.
+
.. c:function:: PyStatus PyConfig_Read(PyConfig *config)
Read all Python configuration.
diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h
index 297fbf70792f..bd07a4829b47 100644
--- a/Include/cpython/initconfig.h
+++ b/Include/cpython/initconfig.h
@@ -422,6 +422,9 @@ PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
Py_ssize_t argc,
wchar_t * const *argv);
+PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
+ PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items);
#ifdef __cplusplus
}
diff --git a/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst b/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
new file mode 100644
index 000000000000..095d58116385
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
@@ -0,0 +1 @@
+Add :func:`PyConfig_SetWideStringList` function.
diff --git a/Python/initconfig.c b/Python/initconfig.c
index 786f6945c171..c44ae6bdfacc 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -732,7 +732,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
} while (0)
#define COPY_WSTRLIST(LIST) \
do { \
- if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
+ if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
return _PyStatus_NO_MEMORY(); \
} \
} while (0)
@@ -2324,6 +2324,23 @@ PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
}
+PyStatus
+PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyWideStringList list2 = {.length = length, .items = items};
+ if (_PyWideStringList_Copy(list, &list2) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+}
+
+
/* Read the configuration into PyConfig from:
* Command line arguments
From webhook-mailer at python.org Mon Jul 1 13:40:03 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 17:40:03 -0000
Subject: [Python-checkins] bpo-36763: Add PyConfig_SetWideStringList()
(GH-14444)
Message-ID:
https://github.com/python/cpython/commit/96f581cf9d2f1d7888d2fd9bb89f19f10c0477bf
commit: 96f581cf9d2f1d7888d2fd9bb89f19f10c0477bf
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T10:39:58-07:00
summary:
bpo-36763: Add PyConfig_SetWideStringList() (GH-14444)
(cherry picked from commit 36242fd871d0f0977e720d4fae5700774bd8c09a)
Co-authored-by: Victor Stinner
files:
A Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
M Doc/c-api/init_config.rst
M Include/cpython/initconfig.h
M Python/initconfig.c
diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst
index 0d94e6b8f27b..d2c1f9a2f3e3 100644
--- a/Doc/c-api/init_config.rst
+++ b/Doc/c-api/init_config.rst
@@ -25,6 +25,7 @@ Functions:
* :c:func:`PyConfig_SetBytesArgv`
* :c:func:`PyConfig_SetBytesString`
* :c:func:`PyConfig_SetString`
+* :c:func:`PyConfig_SetWideStringList`
* :c:func:`PyPreConfig_InitIsolatedConfig`
* :c:func:`PyPreConfig_InitPythonConfig`
* :c:func:`PyStatus_Error`
@@ -368,6 +369,12 @@ PyConfig
Preinitialize Python if needed.
+ .. c:function:: PyStatus PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)
+
+ Set the list of wide strings *list* to *length* and *items*.
+
+ Preinitialize Python if needed.
+
.. c:function:: PyStatus PyConfig_Read(PyConfig *config)
Read all Python configuration.
diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h
index 297fbf70792f..bd07a4829b47 100644
--- a/Include/cpython/initconfig.h
+++ b/Include/cpython/initconfig.h
@@ -422,6 +422,9 @@ PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv(
PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config,
Py_ssize_t argc,
wchar_t * const *argv);
+PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
+ PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items);
#ifdef __cplusplus
}
diff --git a/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst b/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
new file mode 100644
index 000000000000..095d58116385
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst
@@ -0,0 +1 @@
+Add :func:`PyConfig_SetWideStringList` function.
diff --git a/Python/initconfig.c b/Python/initconfig.c
index e791a0d6a09e..1c7078a6b570 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -732,7 +732,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
} while (0)
#define COPY_WSTRLIST(LIST) \
do { \
- if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \
+ if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0) { \
return _PyStatus_NO_MEMORY(); \
} \
} while (0)
@@ -2277,6 +2277,23 @@ PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
}
+PyStatus
+PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items)
+{
+ PyStatus status = _Py_PreInitializeFromConfig(config, NULL);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+
+ PyWideStringList list2 = {.length = length, .items = items};
+ if (_PyWideStringList_Copy(list, &list2) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+ return _PyStatus_OK();
+}
+
+
/* Read the configuration into PyConfig from:
* Command line arguments
From webhook-mailer at python.org Mon Jul 1 13:45:11 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 17:45:11 -0000
Subject: [Python-checkins] bpo-37469: Document usability of SimpleQueue with
QueueHandler and QueueListener. (GH-14521)
Message-ID:
https://github.com/python/cpython/commit/e6b64b756f940147728ea7808fb686ffcae89176
commit: e6b64b756f940147728ea7808fb686ffcae89176
branch: master
author: Vinay Sajip
committer: GitHub
date: 2019-07-01T18:45:07+01:00
summary:
bpo-37469: Document usability of SimpleQueue with QueueHandler and QueueListener. (GH-14521)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index df5bfefaa275..592d7e5daf93 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -992,9 +992,11 @@ possible, while any potentially slow operations (such as sending an email via
.. class:: QueueHandler(queue)
Returns a new instance of the :class:`QueueHandler` class. The instance is
- initialized with the queue to send messages to. The queue can be any
- queue-like object; it's used as-is by the :meth:`enqueue` method, which needs
- to know how to send messages to it.
+ initialized with the queue to send messages to. The *queue* can be any
+ queue-like object; it's used as-is by the :meth:`enqueue` method, which
+ needs to know how to send messages to it. The queue is not *required* to
+ have the task tracking API, which means that you can use
+ :class:`~queue.SimpleQueue` instances for *queue*.
.. method:: emit(record)
@@ -1050,11 +1052,14 @@ possible, while any potentially slow operations (such as sending an email via
initialized with the queue to send messages to and a list of handlers which
will handle entries placed on the queue. The queue can be any queue-like
object; it's passed as-is to the :meth:`dequeue` method, which needs
- to know how to get messages from it. If ``respect_handler_level`` is ``True``,
- a handler's level is respected (compared with the level for the message) when
- deciding whether to pass messages to that handler; otherwise, the behaviour
- is as in previous Python versions - to always pass each message to each
- handler.
+ to know how to get messages from it. The queue is not *required* to have the
+ task tracking API (though it's used if available), which means that you can
+ use :class:`~queue.SimpleQueue` instances for *queue*.
+
+ If ``respect_handler_level`` is ``True``, a handler's level is respected
+ (compared with the level for the message) when deciding whether to pass
+ messages to that handler; otherwise, the behaviour is as in previous Python
+ versions - to always pass each message to each handler.
.. versionchanged:: 3.5
The ``respect_handler_levels`` argument was added.
From webhook-mailer at python.org Mon Jul 1 13:52:52 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 17:52:52 -0000
Subject: [Python-checkins] bpo-36763: Use PyConfig_Clear() (GH-14445)
Message-ID:
https://github.com/python/cpython/commit/67310023f299b5a2fad71fca449b46d280036690
commit: 67310023f299b5a2fad71fca449b46d280036690
branch: master
author: Victor Stinner
committer: GitHub
date: 2019-07-01T19:52:45+02:00
summary:
bpo-36763: Use PyConfig_Clear() (GH-14445)
Stop using "static PyConfig", PyConfig must now always use
dynamically allocated strings: use PyConfig_SetString(),
PyConfig_SetArgv() and PyConfig_Clear().
files:
M Lib/test/test_embed.py
M Modules/main.c
M Programs/_freeze_importlib.c
M Programs/_testembed.c
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index e1cf4be50668..b2cd55016e46 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -695,10 +695,19 @@ def test_init_from_config(self):
'pycache_prefix': 'conf_pycache_prefix',
'program_name': './conf_program_name',
- 'argv': ['-c', 'arg2'],
+ 'argv': ['-c', 'arg2', ],
'parse_argv': 1,
- 'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'],
- 'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
+ 'xoptions': [
+ 'config_xoption1=3',
+ 'config_xoption2=',
+ 'config_xoption3',
+ 'cmdline_xoption',
+ ],
+ 'warnoptions': [
+ 'config_warnoption',
+ 'cmdline_warnoption',
+ 'default::BytesWarning',
+ ],
'run_command': 'pass\n',
'site_import': 0,
diff --git a/Modules/main.c b/Modules/main.c
index 853afedd7b90..b126f4554d41 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -62,7 +62,7 @@ pymain_init(const _PyArgv *args)
PyConfig config;
status = PyConfig_InitPythonConfig(&config);
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
/* pass NULL as the config: config is read from command line arguments,
@@ -74,14 +74,18 @@ pymain_init(const _PyArgv *args)
status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
}
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
status = Py_InitializeFromConfig(&config);
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
- return _PyStatus_OK();
+ status = _PyStatus_OK();
+
+done:
+ PyConfig_Clear(&config);
+ return status;
}
diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c
index 13375b0a3819..74735f279c58 100644
--- a/Programs/_freeze_importlib.c
+++ b/Programs/_freeze_importlib.c
@@ -88,7 +88,7 @@ main(int argc, char *argv[])
config.site_import = 0;
status = PyConfig_SetString(&config, &config.program_name,
- L"./_freeze_importlib");
+ L"./_freeze_importlib");
if (PyStatus_Exception(status)) {
PyConfig_Clear(&config);
Py_ExitStatusException(status);
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 9633f4610b54..856144b85e17 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -329,6 +329,56 @@ static int test_init_initialize_config(void)
}
+static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str)
+{
+ PyStatus status = PyConfig_SetString(config, config_str, str);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
+{
+ PyStatus status = PyConfig_SetArgv(config, argc, argv);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void
+config_set_wide_string_list(PyConfig *config, PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items)
+{
+ PyStatus status = PyConfig_SetWideStringList(config, list, length, items);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void config_set_program_name(PyConfig *config)
+{
+ /* Use path starting with "./" avoids a search along the PATH */
+ const wchar_t *program_name = L"./_testembed";
+ config_set_string(config, &config->program_name, program_name);
+}
+
+
+static void init_from_config_clear(PyConfig *config)
+{
+ PyStatus status = Py_InitializeFromConfig(config);
+ PyConfig_Clear(config);
+ if (PyStatus_Exception(status)) {
+ Py_ExitStatusException(status);
+ }
+}
+
+
static int check_init_compat_config(int preinit)
{
PyStatus status;
@@ -345,12 +395,8 @@ static int check_init_compat_config(int preinit)
PyConfig config;
_PyConfig_InitCompatConfig(&config);
- config.program_name = L"./_testembed";
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
@@ -438,7 +484,6 @@ static int test_init_from_config(void)
Py_ExitStatusException(status);
}
- /* Test Py_InitializeFromConfig() */
PyConfig config;
_PyConfig_InitCompatConfig(&config);
config.install_signal_handlers = 0;
@@ -468,34 +513,37 @@ static int test_init_from_config(void)
config.malloc_stats = 1;
putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
- config.pycache_prefix = L"conf_pycache_prefix";
+ config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix");
Py_SetProgramName(L"./globalvar");
- config.program_name = L"./conf_program_name";
+ config_set_string(&config, &config.program_name, L"./conf_program_name");
- static wchar_t* argv[] = {
+ wchar_t* argv[] = {
L"python3",
+ L"-W",
+ L"cmdline_warnoption",
+ L"-X",
+ L"cmdline_xoption",
L"-c",
L"pass",
L"arg2",
};
- config.argv.length = Py_ARRAY_LENGTH(argv);
- config.argv.items = argv;
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
config.parse_argv = 1;
- static wchar_t* xoptions[3] = {
- L"xoption1=3",
- L"xoption2=",
- L"xoption3",
+ wchar_t* xoptions[3] = {
+ L"config_xoption1=3",
+ L"config_xoption2=",
+ L"config_xoption3",
};
- config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
- config.xoptions.items = xoptions;
+ config_set_wide_string_list(&config, &config.xoptions,
+ Py_ARRAY_LENGTH(xoptions), xoptions);
- static wchar_t* warnoptions[1] = {
- L"error::ResourceWarning",
+ wchar_t* warnoptions[1] = {
+ L"config_warnoption",
};
- config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
- config.warnoptions.items = warnoptions;
+ config_set_wide_string_list(&config, &config.warnoptions,
+ Py_ARRAY_LENGTH(warnoptions), warnoptions);
/* FIXME: test pythonpath_env */
/* FIXME: test home */
@@ -544,22 +592,20 @@ static int test_init_from_config(void)
Force it to 0 through the config. */
config.legacy_windows_stdio = 0;
#endif
- config.stdio_encoding = L"iso8859-1";
- config.stdio_errors = L"replace";
+ config_set_string(&config, &config.stdio_encoding, L"iso8859-1");
+ config_set_string(&config, &config.stdio_errors, L"replace");
putenv("PYTHONNOUSERSITE=");
Py_NoUserSiteDirectory = 0;
config.user_site_directory = 0;
- config.check_hash_pycs_mode = L"always";
+ config_set_string(&config, &config.check_hash_pycs_mode, L"always");
Py_FrozenFlag = 0;
config.pathconfig_warnings = 0;
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -576,7 +622,9 @@ static int check_init_parse_argv(int parse_argv)
Py_ExitStatusException(status);
}
- static wchar_t* argv[] = {
+ config.parse_argv = parse_argv;
+
+ wchar_t* argv[] = {
L"./argv0",
L"-E",
L"-c",
@@ -585,15 +633,9 @@ static int check_init_parse_argv(int parse_argv)
L"-v",
L"arg3",
};
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ init_from_config_clear(&config);
- config.argv.length = Py_ARRAY_LENGTH(argv);
- config.argv.items = argv;
- config.parse_argv = parse_argv;
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
dump_config();
Py_Finalize();
return 0;
@@ -664,12 +706,10 @@ static int test_init_python_env(void)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -723,14 +763,10 @@ static int test_init_isolated_flag(void)
Py_IsolatedFlag = 0;
config.isolated = 1;
- /* Use path starting with "./" avoids a search along the PATH */
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -753,13 +789,10 @@ static int test_preinit_isolated1(void)
PyConfig config;
_PyConfig_InitCompatConfig(&config);
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -787,14 +820,10 @@ static int test_preinit_isolated2(void)
Py_IsolatedFlag = 0;
config.isolated = 1;
- /* Use path starting with "./" avoids a search along the PATH */
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -819,44 +848,28 @@ static int test_preinit_dont_parse_argv(void)
L"script.py"};
status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv);
if (PyStatus_Exception(status)) {
- goto failed;
+ Py_ExitStatusException(status);
}
PyConfig config;
status = PyConfig_InitIsolatedConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
config.isolated = 0;
/* Pre-initialize implicitly using argv: make sure that -X dev
is used to configure the allocation in preinitialization */
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./_testembed");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
return 0;
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
@@ -867,36 +880,20 @@ static int test_preinit_parse_argv(void)
status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
/* Pre-initialize implicitly using argv: make sure that -X dev
is used to configure the allocation in preinitialization */
wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./_testembed");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
return 0;
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
@@ -955,13 +952,8 @@ static int check_preinit_isolated_config(int preinit)
PyConfig_Clear(&config);
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
rt_preconfig = &_PyRuntime.preconfig;
assert(rt_preconfig->isolated == 1);
@@ -1017,12 +1009,9 @@ static int check_init_python_config(int preinit)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
dump_config();
Py_Finalize();
return 0;
@@ -1061,11 +1050,8 @@ static int test_init_dont_configure_locale(void)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
@@ -1084,11 +1070,9 @@ static int test_init_dev_mode(void)
putenv("PYTHONFAULTHANDLER=");
putenv("PYTHONMALLOC=");
config.dev_mode = 1;
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -1278,16 +1262,9 @@ static int test_init_read_set(void)
}
/* override executable computed by PyConfig_Read() */
- status = PyConfig_SetString(&config, &config.executable, L"my_executable");
- if (PyStatus_Exception(status)) {
- goto fail;
- }
+ config_set_string(&config, &config.executable, L"my_executable");
+ init_from_config_clear(&config);
- status = Py_InitializeFromConfig(&config);
- PyConfig_Clear(&config);
- if (PyStatus_Exception(status)) {
- goto fail;
- }
dump_config();
Py_Finalize();
return 0;
@@ -1297,19 +1274,18 @@ static int test_init_read_set(void)
}
-wchar_t *init_main_argv[] = {
- L"python3", L"-c",
- (L"import _testinternalcapi, json; "
- L"print(json.dumps(_testinternalcapi.get_configs()))"),
- L"arg2"};
-
-
static void configure_init_main(PyConfig *config)
{
- config->argv.length = Py_ARRAY_LENGTH(init_main_argv);
- config->argv.items = init_main_argv;
+ wchar_t* argv[] = {
+ L"python3", L"-c",
+ (L"import _testinternalcapi, json; "
+ L"print(json.dumps(_testinternalcapi.get_configs()))"),
+ L"arg2"};
+
config->parse_argv = 1;
- config->program_name = L"./python3";
+
+ config_set_argv(config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_string(config, &config->program_name, L"./python3");
}
@@ -1322,11 +1298,7 @@ static int test_init_run_main(void)
Py_ExitStatusException(status);
}
configure_init_main(&config);
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
return Py_RunMain();
}
@@ -1343,11 +1315,7 @@ static int test_init_main(void)
}
configure_init_main(&config);
config._init_main = 0;
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
int res = PyRun_SimpleString(
@@ -1374,35 +1342,19 @@ static int test_run_main(void)
status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
wchar_t *argv[] = {L"python3", L"-c",
(L"import sys; "
L"print(f'Py_RunMain(): sys.argv={sys.argv}')"),
L"arg2"};
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./python3");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_string(&config, &config.program_name, L"./python3");
+ init_from_config_clear(&config);
return Py_RunMain();
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
From webhook-mailer at python.org Mon Jul 1 14:02:43 2019
From: webhook-mailer at python.org (Victor Stinner)
Date: Mon, 01 Jul 2019 18:02:43 -0000
Subject: [Python-checkins] Remove unused imports in tests (GH-14518)
(GH-14522)
Message-ID:
https://github.com/python/cpython/commit/e34b5f4d6483187969d5149c801d056b72ef2ddb
commit: e34b5f4d6483187969d5149c801d056b72ef2ddb
branch: 3.7
author: Victor Stinner
committer: GitHub
date: 2019-07-01T20:02:39+02:00
summary:
Remove unused imports in tests (GH-14518) (GH-14522)
(cherry picked from commit 8f4ef3b019ce380022018587571b0f970e668de3)
files:
M Lib/test/libregrtest/main.py
M Lib/test/support/__init__.py
M Lib/test/test_aifc.py
M Lib/test/test_argparse.py
M Lib/test/test_asynchat.py
M Lib/test/test_asyncio/test_pep492.py
M Lib/test/test_asyncio/test_sslproto.py
M Lib/test/test_asyncio/test_unix_events.py
M Lib/test/test_c_locale_coercion.py
M Lib/test/test_capi.py
M Lib/test/test_cmd_line.py
M Lib/test/test_collections.py
M Lib/test/test_contextlib.py
M Lib/test/test_coroutines.py
M Lib/test/test_docxmlrpc.py
M Lib/test/test_email/test_policy.py
M Lib/test/test_exceptions.py
M Lib/test/test_faulthandler.py
M Lib/test/test_fork1.py
M Lib/test/test_frozen.py
M Lib/test/test_gdb.py
M Lib/test/test_generators.py
M Lib/test/test_gettext.py
M Lib/test/test_grammar.py
M Lib/test/test_imaplib.py
M Lib/test/test_import/__init__.py
M Lib/test/test_importlib/test_locks.py
M Lib/test/test_locale.py
M Lib/test/test_netrc.py
M Lib/test/test_os.py
M Lib/test/test_posixpath.py
M Lib/test/test_pyclbr.py
M Lib/test/test_pydoc.py
M Lib/test/test_queue.py
M Lib/test/test_resource.py
M Lib/test/test_runpy.py
M Lib/test/test_sax.py
M Lib/test/test_signal.py
M Lib/test/test_smtplib.py
M Lib/test/test_subprocess.py
M Lib/test/test_thread.py
M Lib/test/test_threaded_import.py
M Lib/test/test_threadedtempfile.py
M Lib/test/test_time.py
M Lib/test/test_tokenize.py
M Lib/test/test_traceback.py
M Lib/test/test_utf8_mode.py
M Lib/test/test_venv.py
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 1dfbe47a2fab..e2274254fdb8 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -587,7 +587,6 @@ def create_temp_dir(self):
def cleanup(self):
import glob
- import shutil
path = os.path.join(self.tmp_dir, 'test_python_*')
print("Cleanup %s directory" % self.tmp_dir)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 87bfa9f54627..6d10e8b576e4 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -5,7 +5,6 @@
import collections.abc
import contextlib
-import datetime
import errno
import faulthandler
import fnmatch
@@ -13,7 +12,6 @@
import gc
import importlib
import importlib.util
-import io
import logging.handlers
import nntplib
import os
diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py
index ff52f5b6feb8..e82cfc1a4690 100644
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -7,7 +7,6 @@
import sys
import struct
import aifc
-import warnings
class AifcTest(audiotests.AudioWriteTests,
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 51f0effaf2ff..0c342e2e4e0d 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1,6 +1,5 @@
# Author: Steven J. Bethard .
-import codecs
import inspect
import os
import shutil
diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py
index 1d147c741961..14c0ec43d422 100644
--- a/Lib/test/test_asynchat.py
+++ b/Lib/test/test_asynchat.py
@@ -7,7 +7,6 @@
import errno
import socket
import sys
-import _thread as thread
import threading
import time
import unittest
diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py
index f2d588f54445..ac3ae6811fb5 100644
--- a/Lib/test/test_asyncio/test_pep492.py
+++ b/Lib/test/test_asyncio/test_pep492.py
@@ -4,7 +4,6 @@
import types
import unittest
-from test import support
from unittest import mock
import asyncio
diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py
index 866ef81fb2ee..3b9c12f24ed3 100644
--- a/Lib/test/test_asyncio/test_sslproto.py
+++ b/Lib/test/test_asyncio/test_sslproto.py
@@ -15,7 +15,6 @@
from asyncio import log
from asyncio import protocols
from asyncio import sslproto
-from asyncio import tasks
from test.test_asyncio import utils as test_utils
from test.test_asyncio import functional as func_tests
diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py
index ec171fa83da3..51d474cf152c 100644
--- a/Lib/test/test_asyncio/test_unix_events.py
+++ b/Lib/test/test_asyncio/test_unix_events.py
@@ -22,7 +22,6 @@
import asyncio
from asyncio import log
-from asyncio import base_events
from asyncio import events
from asyncio import unix_events
from test.test_asyncio import utils as test_utils
diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py
index 134f07a17ec1..f2351fa5a2ea 100644
--- a/Lib/test/test_c_locale_coercion.py
+++ b/Lib/test/test_c_locale_coercion.py
@@ -2,7 +2,6 @@
import locale
import os
-import shutil
import subprocess
import sys
import sysconfig
@@ -10,10 +9,8 @@
from collections import namedtuple
import test.support
-from test.support.script_helper import (
- run_python_until_end,
- interpreter_requires_environment,
-)
+from test.support.script_helper import run_python_until_end
+
# Set the list of ways we expect to be able to ask for the "C" locale
EXPECTED_C_LOCALE_EQUIVALENTS = ["C", "invalid.ascii"]
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index d94ee0227c87..6eb3bd967b86 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -8,7 +8,6 @@
import re
import subprocess
import sys
-import sysconfig
import textwrap
import threading
import time
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 95cdc8db7efb..f90bfb067483 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -5,7 +5,6 @@
import os
import subprocess
import sys
-import sysconfig
import tempfile
import unittest
from test import support
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 16735b815e53..1aca9facda69 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -3,11 +3,9 @@
import collections
import copy
import doctest
-import keyword
import operator
import pickle
from random import choice, randrange
-import re
import string
import sys
from test import support
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index 30c2e27b3c7e..ced2290288db 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -1,6 +1,5 @@
"""Unit tests for contextlib.py, and other context managers."""
-import asyncio
import io
import sys
import tempfile
diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py
index ac24f3976738..f32320956bcc 100644
--- a/Lib/test/test_coroutines.py
+++ b/Lib/test/test_coroutines.py
@@ -2,7 +2,6 @@
import copy
import inspect
import pickle
-import re
import sys
import types
import unittest
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
index f077f05f5b4f..116e626740df 100644
--- a/Lib/test/test_docxmlrpc.py
+++ b/Lib/test/test_docxmlrpc.py
@@ -2,7 +2,6 @@
import http.client
import sys
import threading
-from test import support
import unittest
def make_request_and_skipIf(condition, reason):
diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py
index 0aea934df434..1e39aa062c0a 100644
--- a/Lib/test/test_email/test_policy.py
+++ b/Lib/test/test_email/test_policy.py
@@ -1,5 +1,4 @@
import io
-import sys
import types
import textwrap
import unittest
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 9d10df5f9425..0196c4d0005b 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -9,7 +9,7 @@
import errno
from test.support import (TESTFN, captured_stderr, check_impl_detail,
- check_warnings, cpython_only, gc_collect, run_unittest,
+ check_warnings, cpython_only, gc_collect,
no_tracing, unlink, import_module, script_helper,
SuppressCrashReport)
class NaiveException(Exception):
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index 700b7ad6b885..5283596cebe4 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -9,7 +9,6 @@
from test import support
from test.support import script_helper, is_android
import tempfile
-import threading
import unittest
from textwrap import dedent
diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py
index 9ca9724c4c91..2ab856ff5690 100644
--- a/Lib/test/test_fork1.py
+++ b/Lib/test/test_fork1.py
@@ -10,8 +10,7 @@
import unittest
from test.fork_wait import ForkWait
-from test.support import (reap_children, get_attribute,
- import_module, verbose)
+from test.support import reap_children, get_attribute, verbose
# Skip test if fork does not exist.
diff --git a/Lib/test/test_frozen.py b/Lib/test/test_frozen.py
index a7c748422b1d..142f17d518e7 100644
--- a/Lib/test/test_frozen.py
+++ b/Lib/test/test_frozen.py
@@ -13,7 +13,6 @@
import sys
import unittest
from test.support import captured_stdout
-from importlib import util
class TestFrozen(unittest.TestCase):
diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py
index 7758e1fcd86c..b78c0845b1df 100644
--- a/Lib/test/test_gdb.py
+++ b/Lib/test/test_gdb.py
@@ -3,7 +3,6 @@
# The code for testing gdb was adapted from similar work in Unladen Swallow's
# Lib/test/test_jit_gdb.py
-import locale
import os
import platform
import re
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index 7a21cb7e954a..c45086562d36 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -3,7 +3,6 @@
import pickle
import sys
import unittest
-import warnings
import weakref
import inspect
diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py
index b5ed05eab7bb..fac38000e635 100644
--- a/Lib/test/test_gettext.py
+++ b/Lib/test/test_gettext.py
@@ -1,7 +1,6 @@
import os
import base64
import gettext
-import locale
import unittest
from test import support
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index 88c22b89d444..241ac853d73c 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -4,7 +4,6 @@
from test.support import check_syntax_error
import inspect
import unittest
-import sys
# testing import *
from sys import *
@@ -12,7 +11,6 @@
# with import machinery
import test.ann_module as ann_module
import typing
-from collections import ChainMap
from test import ann_module2
import test
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 9305e47ee993..8ab532af3f0d 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -1,7 +1,6 @@
from test import support
from contextlib import contextmanager
-import errno
import imaplib
import os.path
import socketserver
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 1fc4de11e178..4c4f0d9efc03 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -5,7 +5,6 @@
import builtins
import marshal
import os
-import platform
import py_compile
import random
import stat
@@ -20,9 +19,9 @@
import test.support
from test.support import (
- EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython,
- make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask,
- unlink, unload, create_empty_file, cpython_only, TESTFN_UNENCODABLE,
+ TESTFN, forget, is_jython,
+ make_legacy_pyc, rmtree, swap_attr, swap_item, temp_umask,
+ unlink, unload, cpython_only, TESTFN_UNENCODABLE,
temp_dir, DirsOnSysPath)
from test.support import script_helper
from test.test_importlib.util import uncache
diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py
index d86172ab5837..21794d911ef6 100644
--- a/Lib/test/test_importlib/test_locks.py
+++ b/Lib/test/test_importlib/test_locks.py
@@ -4,7 +4,6 @@
import sys
import threading
-import unittest
import weakref
from test import support
diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py
index e2c2178ae6cc..792a15c50f92 100644
--- a/Lib/test/test_locale.py
+++ b/Lib/test/test_locale.py
@@ -3,7 +3,7 @@
import locale
import sys
import codecs
-import warnings
+
class BaseLocalizedTest(unittest.TestCase):
#
diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py
index f59e5371acad..ae53988c45a6 100644
--- a/Lib/test/test_netrc.py
+++ b/Lib/test/test_netrc.py
@@ -1,5 +1,4 @@
import netrc, os, unittest, sys, tempfile, textwrap
-from unittest import mock
from test import support
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 8032da053067..1ec9a6a95091 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -9,7 +9,6 @@
import decimal
import errno
import fractions
-import getpass
import itertools
import locale
import mmap
diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py
index e73b31cb648b..6bca89003a97 100644
--- a/Lib/test/test_posixpath.py
+++ b/Lib/test/test_posixpath.py
@@ -1,7 +1,6 @@
import os
import posixpath
import unittest
-import warnings
from posixpath import realpath, abspath, dirname, basename
from test import support, test_genericpath
from test.support import FakePath
@@ -12,6 +11,7 @@
except ImportError:
posix = None
+
# An absolute path to a temporary filename for testing. We can't rely on TESTFN
# being an absolute path, so we need this.
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index eaab591f74ef..0489b41d7c7b 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -3,14 +3,11 @@
Nick Mathewson
'''
-import os
import sys
from textwrap import dedent
from types import FunctionType, MethodType, BuiltinFunctionType
import pyclbr
from unittest import TestCase, main as unittest_main
-from test import support
-from functools import partial
StaticMethodType = type(staticmethod(lambda: None))
ClassMethodType = type(classmethod(lambda c: None))
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 198cea93eb52..8e30b4c8f675 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -21,7 +21,6 @@
import xml.etree
import xml.etree.ElementTree
import textwrap
-import threading
from io import StringIO
from collections import namedtuple
from test.support.script_helper import assert_python_ok
diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py
index 1a8d5f8856c5..c8528f97741d 100644
--- a/Lib/test/test_queue.py
+++ b/Lib/test/test_queue.py
@@ -1,10 +1,8 @@
# Some simple queue module tests, plus some failure conditions
# to ensure the Queue locks remain stable.
-import collections
import itertools
import queue
import random
-import sys
import threading
import time
import unittest
diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py
index b07eb73b2aeb..62c7963fe699 100644
--- a/Lib/test/test_resource.py
+++ b/Lib/test/test_resource.py
@@ -1,6 +1,5 @@
import contextlib
import sys
-import os
import unittest
from test import support
import time
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index 02b4d62567e5..0da6f3a60430 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -11,8 +11,7 @@
from test.support import (
forget, make_legacy_pyc, unload, verbose, no_tracing,
create_empty_file, temp_dir)
-from test.support.script_helper import (
- make_pkg, make_script, make_zip_pkg, make_zip_script)
+from test.support.script_helper import make_script, make_zip_script
import runpy
diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py
index 3044960a0ed1..251a03a54ddc 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -17,7 +17,6 @@
from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
from io import BytesIO, StringIO
import codecs
-import gc
import os.path
import shutil
from urllib.error import URLError
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 406684bdbec7..c3f5b148448c 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -5,7 +5,6 @@
import statistics
import subprocess
import sys
-import threading
import time
import unittest
from test import support
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index b4149d3ef007..4add8fcabfd1 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -19,7 +19,7 @@
import unittest
from test import support, mock_socket
-from test.support import HOST, HOSTv4, HOSTv6
+from test.support import HOST
from unittest.mock import Mock
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 8419061b2a90..36cf22a9f898 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -3,7 +3,6 @@
from test import support
import subprocess
import sys
-import platform
import signal
import io
import itertools
@@ -20,18 +19,12 @@
import textwrap
from test.support import FakePath
-try:
- import ctypes
-except ImportError:
- ctypes = None
-else:
- import ctypes.util
-
try:
import _testcapi
except ImportError:
_testcapi = None
+
if support.PGO:
raise unittest.SkipTest("test is not helpful for PGO")
diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py
index 64ffe4605298..f4eb830cf6d7 100644
--- a/Lib/test/test_thread.py
+++ b/Lib/test/test_thread.py
@@ -4,7 +4,6 @@
from test import support
import _thread as thread
import time
-import sys
import weakref
from test import lock_tests
diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py
index 035344be4b89..8607f363db21 100644
--- a/Lib/test/test_threaded_import.py
+++ b/Lib/test/test_threaded_import.py
@@ -15,7 +15,7 @@
import unittest
from unittest import mock
from test.support import (
- verbose, import_module, run_unittest, TESTFN, reap_threads,
+ verbose, run_unittest, TESTFN, reap_threads,
forget, unlink, rmtree, start_threads)
def task(N, done, done_tasks, errors):
diff --git a/Lib/test/test_threadedtempfile.py b/Lib/test/test_threadedtempfile.py
index f3d4ba36377d..e1d7a10179cc 100644
--- a/Lib/test/test_threadedtempfile.py
+++ b/Lib/test/test_threadedtempfile.py
@@ -13,19 +13,22 @@
provoking a 2.0 failure under Linux.
"""
-NUM_THREADS = 20
-FILES_PER_THREAD = 50
-
import tempfile
-from test.support import start_threads, import_module
+from test.support import start_threads
import unittest
import io
import threading
from traceback import print_exc
+
+NUM_THREADS = 20
+FILES_PER_THREAD = 50
+
+
startEvent = threading.Event()
+
class TempFileGreedy(threading.Thread):
error_count = 0
ok_count = 0
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 4e31abf4ec8e..35952799ba6d 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -9,7 +9,6 @@
import time
import threading
import unittest
-import warnings
try:
import _testcapi
except ImportError:
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index d596f7db61ab..7457a7ed0434 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -1,7 +1,7 @@
from test import support
from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP,
STRING, ENDMARKER, ENCODING, tok_name, detect_encoding,
- open as tokenize_open, Untokenizer, generate_tokens,
+ open as tokenize_open, Untokenizer,
NEWLINE)
from io import BytesIO
import unittest
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 8a3aa8a8648f..8749d095ddee 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -110,7 +110,7 @@ def test_encoded_file(self):
# Test that tracebacks are correctly printed for encoded source files:
# - correct line number (Issue2384)
# - respect file encoding (Issue3975)
- import tempfile, sys, subprocess, os
+ import sys, subprocess
# The spawned subprocess has its stdout redirected to a PIPE, and its
# encoding may be different from the current interpreter, on Windows
diff --git a/Lib/test/test_utf8_mode.py b/Lib/test/test_utf8_mode.py
index 06fe1979ddcc..a7d1dc940ad6 100644
--- a/Lib/test/test_utf8_mode.py
+++ b/Lib/test/test_utf8_mode.py
@@ -3,7 +3,6 @@
"""
import locale
-import os
import sys
import textwrap
import unittest
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 67f9f46e65e0..3821d9accfdf 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -15,7 +15,6 @@
import tempfile
from test.support import (captured_stdout, captured_stderr, requires_zlib,
can_symlink, EnvironmentVarGuard, rmtree)
-import threading
import unittest
import venv
From webhook-mailer at python.org Mon Jul 1 14:28:59 2019
From: webhook-mailer at python.org (Miss Islington (bot))
Date: Mon, 01 Jul 2019 18:28:59 -0000
Subject: [Python-checkins] bpo-36763: Use PyConfig_Clear() (GH-14445)
Message-ID:
https://github.com/python/cpython/commit/4c227e6a56a9704fe5b4e4509071796f3359f4bb
commit: 4c227e6a56a9704fe5b4e4509071796f3359f4bb
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub
date: 2019-07-01T11:28:55-07:00
summary:
bpo-36763: Use PyConfig_Clear() (GH-14445)
Stop using "static PyConfig", PyConfig must now always use
dynamically allocated strings: use PyConfig_SetString(),
PyConfig_SetArgv() and PyConfig_Clear().
(cherry picked from commit 67310023f299b5a2fad71fca449b46d280036690)
Co-authored-by: Victor Stinner
files:
M Lib/test/test_embed.py
M Modules/main.c
M Programs/_freeze_importlib.c
M Programs/_testembed.c
diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py
index ed1100cfabc5..e31d66d78c85 100644
--- a/Lib/test/test_embed.py
+++ b/Lib/test/test_embed.py
@@ -695,10 +695,19 @@ def test_init_from_config(self):
'pycache_prefix': 'conf_pycache_prefix',
'program_name': './conf_program_name',
- 'argv': ['-c', 'arg2'],
+ 'argv': ['-c', 'arg2', ],
'parse_argv': 1,
- 'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'],
- 'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'],
+ 'xoptions': [
+ 'config_xoption1=3',
+ 'config_xoption2=',
+ 'config_xoption3',
+ 'cmdline_xoption',
+ ],
+ 'warnoptions': [
+ 'config_warnoption',
+ 'cmdline_warnoption',
+ 'default::BytesWarning',
+ ],
'run_command': 'pass\n',
'site_import': 0,
diff --git a/Modules/main.c b/Modules/main.c
index 853afedd7b90..b126f4554d41 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -62,7 +62,7 @@ pymain_init(const _PyArgv *args)
PyConfig config;
status = PyConfig_InitPythonConfig(&config);
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
/* pass NULL as the config: config is read from command line arguments,
@@ -74,14 +74,18 @@ pymain_init(const _PyArgv *args)
status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv);
}
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
status = Py_InitializeFromConfig(&config);
if (_PyStatus_EXCEPTION(status)) {
- return status;
+ goto done;
}
- return _PyStatus_OK();
+ status = _PyStatus_OK();
+
+done:
+ PyConfig_Clear(&config);
+ return status;
}
diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c
index 13375b0a3819..74735f279c58 100644
--- a/Programs/_freeze_importlib.c
+++ b/Programs/_freeze_importlib.c
@@ -88,7 +88,7 @@ main(int argc, char *argv[])
config.site_import = 0;
status = PyConfig_SetString(&config, &config.program_name,
- L"./_freeze_importlib");
+ L"./_freeze_importlib");
if (PyStatus_Exception(status)) {
PyConfig_Clear(&config);
Py_ExitStatusException(status);
diff --git a/Programs/_testembed.c b/Programs/_testembed.c
index 9633f4610b54..856144b85e17 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -329,6 +329,56 @@ static int test_init_initialize_config(void)
}
+static void config_set_string(PyConfig *config, wchar_t **config_str, const wchar_t *str)
+{
+ PyStatus status = PyConfig_SetString(config, config_str, str);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void config_set_argv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
+{
+ PyStatus status = PyConfig_SetArgv(config, argc, argv);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void
+config_set_wide_string_list(PyConfig *config, PyWideStringList *list,
+ Py_ssize_t length, wchar_t **items)
+{
+ PyStatus status = PyConfig_SetWideStringList(config, list, length, items);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(config);
+ Py_ExitStatusException(status);
+ }
+}
+
+
+static void config_set_program_name(PyConfig *config)
+{
+ /* Use path starting with "./" avoids a search along the PATH */
+ const wchar_t *program_name = L"./_testembed";
+ config_set_string(config, &config->program_name, program_name);
+}
+
+
+static void init_from_config_clear(PyConfig *config)
+{
+ PyStatus status = Py_InitializeFromConfig(config);
+ PyConfig_Clear(config);
+ if (PyStatus_Exception(status)) {
+ Py_ExitStatusException(status);
+ }
+}
+
+
static int check_init_compat_config(int preinit)
{
PyStatus status;
@@ -345,12 +395,8 @@ static int check_init_compat_config(int preinit)
PyConfig config;
_PyConfig_InitCompatConfig(&config);
- config.program_name = L"./_testembed";
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
@@ -438,7 +484,6 @@ static int test_init_from_config(void)
Py_ExitStatusException(status);
}
- /* Test Py_InitializeFromConfig() */
PyConfig config;
_PyConfig_InitCompatConfig(&config);
config.install_signal_handlers = 0;
@@ -468,34 +513,37 @@ static int test_init_from_config(void)
config.malloc_stats = 1;
putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
- config.pycache_prefix = L"conf_pycache_prefix";
+ config_set_string(&config, &config.pycache_prefix, L"conf_pycache_prefix");
Py_SetProgramName(L"./globalvar");
- config.program_name = L"./conf_program_name";
+ config_set_string(&config, &config.program_name, L"./conf_program_name");
- static wchar_t* argv[] = {
+ wchar_t* argv[] = {
L"python3",
+ L"-W",
+ L"cmdline_warnoption",
+ L"-X",
+ L"cmdline_xoption",
L"-c",
L"pass",
L"arg2",
};
- config.argv.length = Py_ARRAY_LENGTH(argv);
- config.argv.items = argv;
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
config.parse_argv = 1;
- static wchar_t* xoptions[3] = {
- L"xoption1=3",
- L"xoption2=",
- L"xoption3",
+ wchar_t* xoptions[3] = {
+ L"config_xoption1=3",
+ L"config_xoption2=",
+ L"config_xoption3",
};
- config.xoptions.length = Py_ARRAY_LENGTH(xoptions);
- config.xoptions.items = xoptions;
+ config_set_wide_string_list(&config, &config.xoptions,
+ Py_ARRAY_LENGTH(xoptions), xoptions);
- static wchar_t* warnoptions[1] = {
- L"error::ResourceWarning",
+ wchar_t* warnoptions[1] = {
+ L"config_warnoption",
};
- config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions);
- config.warnoptions.items = warnoptions;
+ config_set_wide_string_list(&config, &config.warnoptions,
+ Py_ARRAY_LENGTH(warnoptions), warnoptions);
/* FIXME: test pythonpath_env */
/* FIXME: test home */
@@ -544,22 +592,20 @@ static int test_init_from_config(void)
Force it to 0 through the config. */
config.legacy_windows_stdio = 0;
#endif
- config.stdio_encoding = L"iso8859-1";
- config.stdio_errors = L"replace";
+ config_set_string(&config, &config.stdio_encoding, L"iso8859-1");
+ config_set_string(&config, &config.stdio_errors, L"replace");
putenv("PYTHONNOUSERSITE=");
Py_NoUserSiteDirectory = 0;
config.user_site_directory = 0;
- config.check_hash_pycs_mode = L"always";
+ config_set_string(&config, &config.check_hash_pycs_mode, L"always");
Py_FrozenFlag = 0;
config.pathconfig_warnings = 0;
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -576,7 +622,9 @@ static int check_init_parse_argv(int parse_argv)
Py_ExitStatusException(status);
}
- static wchar_t* argv[] = {
+ config.parse_argv = parse_argv;
+
+ wchar_t* argv[] = {
L"./argv0",
L"-E",
L"-c",
@@ -585,15 +633,9 @@ static int check_init_parse_argv(int parse_argv)
L"-v",
L"arg3",
};
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ init_from_config_clear(&config);
- config.argv.length = Py_ARRAY_LENGTH(argv);
- config.argv.items = argv;
- config.parse_argv = parse_argv;
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
dump_config();
Py_Finalize();
return 0;
@@ -664,12 +706,10 @@ static int test_init_python_env(void)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -723,14 +763,10 @@ static int test_init_isolated_flag(void)
Py_IsolatedFlag = 0;
config.isolated = 1;
- /* Use path starting with "./" avoids a search along the PATH */
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -753,13 +789,10 @@ static int test_preinit_isolated1(void)
PyConfig config;
_PyConfig_InitCompatConfig(&config);
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -787,14 +820,10 @@ static int test_preinit_isolated2(void)
Py_IsolatedFlag = 0;
config.isolated = 1;
- /* Use path starting with "./" avoids a search along the PATH */
- config.program_name = L"./_testembed";
-
+ config_set_program_name(&config);
set_all_env_vars();
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -819,44 +848,28 @@ static int test_preinit_dont_parse_argv(void)
L"script.py"};
status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv);
if (PyStatus_Exception(status)) {
- goto failed;
+ Py_ExitStatusException(status);
}
PyConfig config;
status = PyConfig_InitIsolatedConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
config.isolated = 0;
/* Pre-initialize implicitly using argv: make sure that -X dev
is used to configure the allocation in preinitialization */
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./_testembed");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
return 0;
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
@@ -867,36 +880,20 @@ static int test_preinit_parse_argv(void)
status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
/* Pre-initialize implicitly using argv: make sure that -X dev
is used to configure the allocation in preinitialization */
wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./_testembed");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
return 0;
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
@@ -955,13 +952,8 @@ static int check_preinit_isolated_config(int preinit)
PyConfig_Clear(&config);
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
rt_preconfig = &_PyRuntime.preconfig;
assert(rt_preconfig->isolated == 1);
@@ -1017,12 +1009,9 @@ static int check_init_python_config(int preinit)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
dump_config();
Py_Finalize();
return 0;
@@ -1061,11 +1050,8 @@ static int test_init_dont_configure_locale(void)
if (PyStatus_Exception(status)) {
Py_ExitStatusException(status);
}
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
dump_config();
Py_Finalize();
@@ -1084,11 +1070,9 @@ static int test_init_dev_mode(void)
putenv("PYTHONFAULTHANDLER=");
putenv("PYTHONMALLOC=");
config.dev_mode = 1;
- config.program_name = L"./_testembed";
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ config_set_program_name(&config);
+ init_from_config_clear(&config);
+
dump_config();
Py_Finalize();
return 0;
@@ -1278,16 +1262,9 @@ static int test_init_read_set(void)
}
/* override executable computed by PyConfig_Read() */
- status = PyConfig_SetString(&config, &config.executable, L"my_executable");
- if (PyStatus_Exception(status)) {
- goto fail;
- }
+ config_set_string(&config, &config.executable, L"my_executable");
+ init_from_config_clear(&config);
- status = Py_InitializeFromConfig(&config);
- PyConfig_Clear(&config);
- if (PyStatus_Exception(status)) {
- goto fail;
- }
dump_config();
Py_Finalize();
return 0;
@@ -1297,19 +1274,18 @@ static int test_init_read_set(void)
}
-wchar_t *init_main_argv[] = {
- L"python3", L"-c",
- (L"import _testinternalcapi, json; "
- L"print(json.dumps(_testinternalcapi.get_configs()))"),
- L"arg2"};
-
-
static void configure_init_main(PyConfig *config)
{
- config->argv.length = Py_ARRAY_LENGTH(init_main_argv);
- config->argv.items = init_main_argv;
+ wchar_t* argv[] = {
+ L"python3", L"-c",
+ (L"import _testinternalcapi, json; "
+ L"print(json.dumps(_testinternalcapi.get_configs()))"),
+ L"arg2"};
+
config->parse_argv = 1;
- config->program_name = L"./python3";
+
+ config_set_argv(config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_string(config, &config->program_name, L"./python3");
}
@@ -1322,11 +1298,7 @@ static int test_init_run_main(void)
Py_ExitStatusException(status);
}
configure_init_main(&config);
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
return Py_RunMain();
}
@@ -1343,11 +1315,7 @@ static int test_init_main(void)
}
configure_init_main(&config);
config._init_main = 0;
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- Py_ExitStatusException(status);
- }
+ init_from_config_clear(&config);
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
int res = PyRun_SimpleString(
@@ -1374,35 +1342,19 @@ static int test_run_main(void)
status = PyConfig_InitPythonConfig(&config);
if (PyStatus_Exception(status)) {
- goto failed;
+ PyConfig_Clear(&config);
+ Py_ExitStatusException(status);
}
wchar_t *argv[] = {L"python3", L"-c",
(L"import sys; "
L"print(f'Py_RunMain(): sys.argv={sys.argv}')"),
L"arg2"};
- status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = PyConfig_SetString(&config, &config.program_name,
- L"./python3");
- if (PyStatus_Exception(status)) {
- goto failed;
- }
-
- status = Py_InitializeFromConfig(&config);
- if (PyStatus_Exception(status)) {
- goto failed;
- }
- PyConfig_Clear(&config);
+ config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
+ config_set_string(&config, &config.program_name, L"./python3");
+ init_from_config_clear(&config);
return Py_RunMain();
-
-failed:
- PyConfig_Clear(&config);
- Py_ExitStatusException(status);
}
From webhook-mailer at python.org Mon Jul 1 14:53:02 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 18:53:02 -0000
Subject: [Python-checkins] bpo-37469: Document usability of SimpleQueue with
QueueHandler and QueueListener. (GH-14521) (GH-14526)
Message-ID:
https://github.com/python/cpython/commit/b0ab95bbe792b38e952688f8fa1657a78b35410e
commit: b0ab95bbe792b38e952688f8fa1657a78b35410e
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T19:52:57+01:00
summary:
bpo-37469: Document usability of SimpleQueue with QueueHandler and QueueListener. (GH-14521) (GH-14526)
(cherry picked from commit e6b64b756f940147728ea7808fb686ffcae89176)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index b2ebafa83b2e..d5944ec87d2d 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -971,9 +971,11 @@ possible, while any potentially slow operations (such as sending an email via
.. class:: QueueHandler(queue)
Returns a new instance of the :class:`QueueHandler` class. The instance is
- initialized with the queue to send messages to. The queue can be any
- queue-like object; it's used as-is by the :meth:`enqueue` method, which needs
- to know how to send messages to it.
+ initialized with the queue to send messages to. The *queue* can be any
+ queue-like object; it's used as-is by the :meth:`enqueue` method, which
+ needs to know how to send messages to it. The queue is not *required* to
+ have the task tracking API, which means that you can use
+ :class:`~queue.SimpleQueue` instances for *queue*.
.. method:: emit(record)
@@ -1029,11 +1031,14 @@ possible, while any potentially slow operations (such as sending an email via
initialized with the queue to send messages to and a list of handlers which
will handle entries placed on the queue. The queue can be any queue-like
object; it's passed as-is to the :meth:`dequeue` method, which needs
- to know how to get messages from it. If ``respect_handler_level`` is ``True``,
- a handler's level is respected (compared with the level for the message) when
- deciding whether to pass messages to that handler; otherwise, the behaviour
- is as in previous Python versions - to always pass each message to each
- handler.
+ to know how to get messages from it. The queue is not *required* to have the
+ task tracking API (though it's used if available), which means that you can
+ use :class:`~queue.SimpleQueue` instances for *queue*.
+
+ If ``respect_handler_level`` is ``True``, a handler's level is respected
+ (compared with the level for the message) when deciding whether to pass
+ messages to that handler; otherwise, the behaviour is as in previous Python
+ versions - to always pass each message to each handler.
.. versionchanged:: 3.5
The ``respect_handler_levels`` argument was added.
From webhook-mailer at python.org Mon Jul 1 14:53:32 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 18:53:32 -0000
Subject: [Python-checkins] bpo-37469: Document usability of SimpleQueue with
QueueHandler and QueueListener. (GH-14521) (GH-14525)
Message-ID:
https://github.com/python/cpython/commit/6cde61369e8174c493ca240cb52ebc9c2a2fe667
commit: 6cde61369e8174c493ca240cb52ebc9c2a2fe667
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T19:53:28+01:00
summary:
bpo-37469: Document usability of SimpleQueue with QueueHandler and QueueListener. (GH-14521) (GH-14525)
(cherry picked from commit e6b64b756f940147728ea7808fb686ffcae89176)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index b2ebafa83b2e..d5944ec87d2d 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -971,9 +971,11 @@ possible, while any potentially slow operations (such as sending an email via
.. class:: QueueHandler(queue)
Returns a new instance of the :class:`QueueHandler` class. The instance is
- initialized with the queue to send messages to. The queue can be any
- queue-like object; it's used as-is by the :meth:`enqueue` method, which needs
- to know how to send messages to it.
+ initialized with the queue to send messages to. The *queue* can be any
+ queue-like object; it's used as-is by the :meth:`enqueue` method, which
+ needs to know how to send messages to it. The queue is not *required* to
+ have the task tracking API, which means that you can use
+ :class:`~queue.SimpleQueue` instances for *queue*.
.. method:: emit(record)
@@ -1029,11 +1031,14 @@ possible, while any potentially slow operations (such as sending an email via
initialized with the queue to send messages to and a list of handlers which
will handle entries placed on the queue. The queue can be any queue-like
object; it's passed as-is to the :meth:`dequeue` method, which needs
- to know how to get messages from it. If ``respect_handler_level`` is ``True``,
- a handler's level is respected (compared with the level for the message) when
- deciding whether to pass messages to that handler; otherwise, the behaviour
- is as in previous Python versions - to always pass each message to each
- handler.
+ to know how to get messages from it. The queue is not *required* to have the
+ task tracking API (though it's used if available), which means that you can
+ use :class:`~queue.SimpleQueue` instances for *queue*.
+
+ If ``respect_handler_level`` is ``True``, a handler's level is respected
+ (compared with the level for the message) when deciding whether to pass
+ messages to that handler; otherwise, the behaviour is as in previous Python
+ versions - to always pass each message to each handler.
.. versionchanged:: 3.5
The ``respect_handler_levels`` argument was added.
From webhook-mailer at python.org Mon Jul 1 15:45:09 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 19:45:09 -0000
Subject: [Python-checkins] bpo-37470: Document more clearly the error
handling for QueueHandler.emit(). (GH-14532)
Message-ID:
https://github.com/python/cpython/commit/0f4e8132820947d93eccf31b9e526b81c6ffa53d
commit: 0f4e8132820947d93eccf31b9e526b81c6ffa53d
branch: master
author: Vinay Sajip
committer: GitHub
date: 2019-07-01T20:45:01+01:00
summary:
bpo-37470: Document more clearly the error handling for QueueHandler.emit(). (GH-14532)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 592d7e5daf93..b7445a135b74 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -1001,7 +1001,12 @@ possible, while any potentially slow operations (such as sending an email via
.. method:: emit(record)
- Enqueues the result of preparing the LogRecord.
+ Enqueues the result of preparing the LogRecord. Should an exception
+ occur (e.g. because a bounded queue has filled up), the
+ :meth:`~logging.Handler.handleError` method is called to handle the
+ error. This can result in the record silently being dropped (if
+ :attr:`logging.raiseExceptions` is ``False``) or a message printed to
+ ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``).
.. method:: prepare(record)
From webhook-mailer at python.org Mon Jul 1 15:51:25 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 19:51:25 -0000
Subject: [Python-checkins] bpo-37470: Document more clearly the error
handling for QueueHandler.emit(). (GH-14532) (GH-14534)
Message-ID:
https://github.com/python/cpython/commit/844a9d64a4f640d1b20dc6ea54ab375680332d93
commit: 844a9d64a4f640d1b20dc6ea54ab375680332d93
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T20:51:20+01:00
summary:
bpo-37470: Document more clearly the error handling for QueueHandler.emit(). (GH-14532) (GH-14534)
(cherry picked from commit 0f4e8132820947d93eccf31b9e526b81c6ffa53d)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index d5944ec87d2d..32919c1a2e29 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -980,7 +980,12 @@ possible, while any potentially slow operations (such as sending an email via
.. method:: emit(record)
- Enqueues the result of preparing the LogRecord.
+ Enqueues the result of preparing the LogRecord. Should an exception
+ occur (e.g. because a bounded queue has filled up), the
+ :meth:`~logging.Handler.handleError` method is called to handle the
+ error. This can result in the record silently being dropped (if
+ :attr:`logging.raiseExceptions` is ``False``) or a message printed to
+ ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``).
.. method:: prepare(record)
From webhook-mailer at python.org Mon Jul 1 15:53:43 2019
From: webhook-mailer at python.org (Vinay Sajip)
Date: Mon, 01 Jul 2019 19:53:43 -0000
Subject: [Python-checkins] bpo-37470: Document more clearly the error
handling for QueueHandler.emit(). (GH-14532) (GH-14533)
Message-ID:
https://github.com/python/cpython/commit/91f9f098fcdb023dbb89d06c8833e89a11cbae4c
commit: 91f9f098fcdb023dbb89d06c8833e89a11cbae4c
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Vinay Sajip
date: 2019-07-01T20:53:39+01:00
summary:
bpo-37470: Document more clearly the error handling for QueueHandler.emit(). (GH-14532) (GH-14533)
(cherry picked from commit 0f4e8132820947d93eccf31b9e526b81c6ffa53d)
files:
M Doc/library/logging.handlers.rst
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index d5944ec87d2d..32919c1a2e29 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -980,7 +980,12 @@ possible, while any potentially slow operations (such as sending an email via
.. method:: emit(record)
- Enqueues the result of preparing the LogRecord.
+ Enqueues the result of preparing the LogRecord. Should an exception
+ occur (e.g. because a bounded queue has filled up), the
+ :meth:`~logging.Handler.handleError` method is called to handle the
+ error. This can result in the record silently being dropped (if
+ :attr:`logging.raiseExceptions` is ``False``) or a message printed to
+ ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``).
.. method:: prepare(record)
From webhook-mailer at python.org Mon Jul 1 19:03:59 2019
From: webhook-mailer at python.org (Steve Dower)
Date: Mon, 01 Jul 2019 23:03:59 -0000
Subject: [Python-checkins] bpo-37363: Add audit events on startup for the
run commands (GH-14524)
Message-ID:
https://github.com/python/cpython/commit/e226e83d36dfc7220d836fb7a249ce18e70cb4a6
commit: e226e83d36dfc7220d836fb7a249ce18e70cb4a6
branch: master
author: Steve Dower
committer: GitHub
date: 2019-07-01T16:03:53-07:00
summary:
bpo-37363: Add audit events on startup for the run commands (GH-14524)
files:
A Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst
M Doc/library/sys.rst
M Doc/tools/extensions/pyspecific.py
M Doc/using/cmdline.rst
M Lib/test/test_embed.py
M Modules/main.c
M Programs/_testembed.c
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 131aea0def62..acd54421a370 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -905,6 +905,12 @@ always available.
read, so that you can set this hook there. The :mod:`site` module
:ref:`sets this `.
+ .. audit-event:: cpython.run_interactivehook hook sys.__interactivehook__
+
+ Raises an :ref:`auditing event `
+ ``cpython.run_interactivehook`` with the hook object as the argument when
+ the hook is called on startup.
+
.. versionadded:: 3.4
diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py
index a6f39b02b5f8..8839033b983c 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -199,13 +199,18 @@ def run(self):
.format(name, info['args'], new_info['args'])
)
- if len(self.arguments) >= 3 and self.arguments[2]:
- target = self.arguments[2]
- ids = []
- else:
- target = "audit_event_{}_{}".format(name, len(info['source']))
- target = re.sub(r'\W', '_', label)
- ids = [target]
+ ids = []
+ try:
+ target = self.arguments[2].strip("\"'")
+ except (IndexError, TypeError):
+ target = None
+ if not target:
+ target = "audit_event_{}_{}".format(
+ re.sub(r'\W', '_', name),
+ len(info['source']),
+ )
+ ids.append(target)
+
info['source'].append((env.docname, target))
pnode = nodes.paragraph(text, classes=["audit-hook"], ids=ids)
@@ -560,7 +565,8 @@ def process_audit_events(app, doctree, fromdocname):
row += nodes.entry('', node)
node = nodes.paragraph()
- for i, (doc, label) in enumerate(audit_event['source'], start=1):
+ backlinks = enumerate(sorted(set(audit_event['source'])), start=1)
+ for i, (doc, label) in backlinks:
if isinstance(label, str):
ref = nodes.reference("", nodes.Text("[{}]".format(i)), internal=True)
ref['refuri'] = "{}#{}".format(
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index e11fe31c2fbb..22f42d966a55 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -70,6 +70,7 @@ source.
:data:`sys.path` (allowing modules in that directory to be imported as top
level modules).
+ .. audit-event:: cpython.run_command command cmdoption-c
.. cmdoption:: -m
@@ -106,13 +107,14 @@ source.
python -mtimeit -s 'setup here' 'benchmarked code here'
python -mtimeit -h # for details
+ .. audit-event:: cpython.run_module module-name cmdoption-m
+
.. seealso::
:func:`runpy.run_module`
Equivalent functionality directly available to Python code
:pep:`338` -- Executing modules as scripts
-
.. versionchanged:: 3.1
Supply the package name to run a ``__main__`` submodule.
@@ -129,6 +131,7 @@ source.
``"-"`` and the current directory will be added to the start of
:data:`sys.path`.
+ .. audit-event:: cpython.run_stdin "" ""
.. describe::
-
+
@@ -135,113 +135,75 @@ Menus
+The IDLE code running in the execution process adds frames to the call stack
+that would not be there otherwise. IDLE wraps sys.getrecursionlimit
and
+sys.setrecursionlimit
to reduce their visibility.
If sys
is reset by user code, such as with importlib.reload(sys)
,
IDLE?s changes are lost and input from the keyboard and output to the screen
will not work correctly.
@@ -772,7 +710,7 @@ Running without a subprocess
Next topic
Other Graphical User Interface Packages
@@ -957,11 +895,11 @@ Navigation
- Last updated on Jun 17, 2019.
+ Last updated on Jul 04, 2019.
Found a bug?
- Created using Sphinx 1.8.1.
+ Created using Sphinx 2.1.1.