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

File menu (Shell and Editor)?

-
New File
-
Create a new file editing window.
-
Open?
-
Open an existing file with an Open dialog.
-
Recent Files
-
Open a list of recent files. Click one to open it.
-
Open Module?
-
Open an existing module (searches sys.path).
+
New File
Create a new file editing window.
+
Open?
Open an existing file with an Open dialog.
+
Recent Files
Open a list of recent files. Click one to open it.
+
Open Module?
Open an existing module (searches sys.path).
-
Class Browser
-
Show functions, classes, and methods in the current Editor file in a +
Class Browser
Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.
-
Path Browser
-
Show sys.path directories, modules, functions, classes and methods in a +
Path Browser
Show sys.path directories, modules, functions, classes and methods in a tree structure.
-
Save
-
Save the current window to the associated file, if there is one. Windows +
Save
Save the current window to the associated file, if there is one. Windows that have been changed since being opened or last saved have a * before and after the window title. If there is no associated file, do Save As instead.
-
Save As?
-
Save the current window with a Save As dialog. The file saved becomes the +
Save As?
Save the current window with a Save As dialog. The file saved becomes the new associated file for the window.
-
Save Copy As?
-
Save the current window to different file without changing the associated +
Save Copy As?
Save the current window to different file without changing the associated file.
-
Print Window
-
Print the current window to the default printer.
-
Close
-
Close the current window (ask to save if unsaved).
-
Exit
-
Close all windows and quit IDLE (ask to save unsaved windows).
+
Print Window
Print the current window to the default printer.
+
Close
Close the current window (ask to save if unsaved).
+
Exit
Close all windows and quit IDLE (ask to save unsaved windows).

Edit menu (Shell and Editor)?

-
Undo
-
Undo the last change to the current window. A maximum of 1000 changes may +
Undo
Undo the last change to the current window. A maximum of 1000 changes may be undone.
-
Redo
-
Redo the last undone change to the current window.
-
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Redo
Redo the last undone change to the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

The clipboard functions are also available in context menus.

-
Select All
-
Select the entire contents of the current window.
-
Find?
-
Open a search dialog with many options
-
Find Again
-
Repeat the last search, if there is one.
-
Find Selection
-
Search for the currently selected string, if there is one.
-
Find in Files?
-
Open a file search dialog. Put results in a new output window.
-
Replace?
-
Open a search-and-replace dialog.
-
Go to Line
-
Move cursor to the line number requested and make that line visible.
-
Show Completions
-
Open a scrollable list allowing selection of keywords and attributes. See +
Select All
Select the entire contents of the current window.
+
Find?
Open a search dialog with many options
+
Find Again
Repeat the last search, if there is one.
+
Find Selection
Search for the currently selected string, if there is one.
+
Find in Files?
Open a file search dialog. Put results in a new output window.
+
Replace?
Open a search-and-replace dialog.
+
Go to Line
Move cursor to the line number requested and make that line visible.
+
Show Completions
Open a scrollable list allowing selection of keywords and attributes. See Completions in the Editing and navigation section below.
-
Expand Word
-
Expand a prefix you have typed to match a full word in the same window; +
Expand Word
Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.
-
Show call tip
-
After an unclosed parenthesis for a function, open a small window with +
Show call tip
After an unclosed parenthesis for a function, open a small window with function parameter hints. See Calltips in the Editing and navigation section below.
-
Show surrounding parens
-
Highlight the surrounding parenthesis.
+
Show surrounding parens
Highlight the surrounding parenthesis.

Format menu (Editor window only)?

-
Indent Region
-
Shift selected lines right by the indent width (default 4 spaces).
-
Dedent Region
-
Shift selected lines left by the indent width (default 4 spaces).
-
Comment Out Region
-
Insert ## in front of selected lines.
-
Uncomment Region
-
Remove leading # or ## from selected lines.
-
Tabify Region
-
Turn leading stretches of spaces into tabs. (Note: We recommend using +
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
+
Dedent Region
Shift selected lines left by the indent width (default 4 spaces).
+
Comment Out Region
Insert ## in front of selected lines.
+
Uncomment Region
Remove leading # or ## from selected lines.
+
Tabify Region
Turn leading stretches of spaces into tabs. (Note: We recommend using 4 space blocks to indent Python code.)
-
Untabify Region
-
Turn all tabs into the correct number of spaces.
-
Toggle Tabs
-
Open a dialog to switch between indenting with spaces and tabs.
-
New Indent Width
-
Open a dialog to change indent width. The accepted default by the Python +
Untabify Region
Turn all tabs into the correct number of spaces.
+
Toggle Tabs
Open a dialog to switch between indenting with spaces and tabs.
+
New Indent Width
Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.
-
Format Paragraph
-
Reformat the current blank-line-delimited paragraph in comment block or +
Format Paragraph
Reformat the current blank-line-delimited paragraph in comment block or multiline string or selected line in a string. All lines in the paragraph will be formatted to less than N columns, where N defaults to 72.
-
Strip trailing whitespace
-
Remove trailing space and other whitespace characters after the last +
Strip trailing whitespace
Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings.
@@ -249,20 +211,17 @@

Edit menu (Shell and Editor)

Run menu (Editor window only)?

-
Python Shell
-
Open or wake up the Python Shell window.
+
Python Shell
Open or wake up the Python Shell window.
-
Check Module
-
Check the syntax of the module currently open in the Editor window. If the +
Check Module
Check the syntax of the module currently open in the Editor window. If the module has not been saved IDLE will either prompt the user to save or autosave, as selected in the General tab of the Idle Settings dialog. If there is a syntax error, the approximate location is indicated in the Editor window.
-
Run Module
-
Do Check Module. If no error, restart the shell to clean the +
Run Module
Do Check Module. If no error, restart the shell to clean the environment, then execute the module. Output is displayed in the Shell window. Note that output requires use of print or write. When execution is complete, the Shell retains focus and displays a prompt. @@ -271,8 +230,7 @@

Edit menu (Shell and Editor) -
Run? Customized
-
Same as Run Module, but run the module with customized +
Run? Customized
Same as Run Module, but run the module with customized settings. Command Line Arguments extend sys.argv as if passed on a command line. The module can be run in the Shell without restarting.

@@ -280,56 +238,44 @@

Edit menu (Shell and Editor)

Shell menu (Shell window only)?

-
View Last Restart
-
Scroll the shell window to the last Shell restart.
-
Restart Shell
-
Restart the shell to clean the environment.
-
Previous History
-
Cycle through earlier commands in history which match the current entry.
-
Next History
-
Cycle through later commands in history which match the current entry.
-
Interrupt Execution
-
Stop a running program.
+
View Last Restart
Scroll the shell window to the last Shell restart.
+
Restart Shell
Restart the shell to clean the environment.
+
Previous History
Cycle through earlier commands in history which match the current entry.
+
Next History
Cycle through later commands in history which match the current entry.
+
Interrupt Execution
Stop a running program.

Debug menu (Shell window only)?

-
Go to File/Line
-
Look on the current line. with the cursor, and the line above for a filename +
Go to File/Line
Look on the current line. with the cursor, and the line above for a filename and line number. If found, open the file if not already open, and show the line. Use this to view source lines referenced in an exception traceback and lines found by Find in Files. Also available in the context menu of the Shell window and Output windows.
-
Debugger (toggle)
-
When activated, code entered in the Shell or run from an Editor will run +
Debugger (toggle)
When activated, code entered in the Shell or run from an Editor will run under the debugger. In the Editor, breakpoints can be set with the context menu. This feature is still incomplete and somewhat experimental.
-
Stack Viewer
-
Show the stack traceback of the last exception in a tree widget, with +
Stack Viewer
Show the stack traceback of the last exception in a tree widget, with access to locals and globals.
-
Auto-open Stack Viewer
-
Toggle automatically opening the stack viewer on an unhandled exception.
+
Auto-open Stack Viewer
Toggle automatically opening the stack viewer on an unhandled exception.

Options menu (Shell and Editor)?

-
Configure IDLE
-
Open a configuration dialog and change preferences for the following: +
Configure IDLE
Open a configuration dialog and change preferences for the following: fonts, indentation, keybindings, text color themes, startup windows and size, additional help sources, and extensions. On macOS, open the configuration dialog by selecting Preferences in the application menu. For more, see Setting preferences under Help and preferences.
-
Show/Hide Code Context (Editor Window only)
-
Open a pane at the top of the edit window which shows the block context +
Show/Hide Code Context (Editor Window only)
Open a pane at the top of the edit window which shows the block context of the code which has scrolled above the top of the window. See Code Context in the Editing and Navigation section below.
-
Zoom/Restore Height
-
Toggles the window between normal size and maximum height. The initial size +
Zoom/Restore Height
Toggles the window between normal size and maximum height. The initial size defaults to 40 lines by 80 chars unless changed on the General tab of the Configure IDLE dialog. The maximum height for a screen is determined by momentarily maximizing a window the first time one is zoomed on the screen. @@ -345,16 +291,12 @@

Window menu (Shell and Editor)

Help menu (Shell and Editor)?

-
About IDLE
-
Display version, copyright, license, credits, and more.
-
IDLE Help
-
Display this IDLE document, detailing the menu options, basic editing and +
About IDLE
Display version, copyright, license, credits, and more.
+
IDLE Help
Display this IDLE document, detailing the menu options, basic editing and navigation, and other tips.
-
Python Docs
-
Access local Python documentation, if installed, or start a web browser +
Python Docs
Access local Python documentation, if installed, or start a web browser and open docs.python.org showing the latest Python documentation.
-
Turtle Demo
-
Run the turtledemo module with example Python code and turtle drawings.
+
Turtle Demo
Run the turtledemo module with example Python code and turtle drawings.

Additional help sources may be added here with the Configure IDLE dialog under the General tab. See the Help sources subsection below @@ -365,32 +307,25 @@

Help menu (Shell and Editor) -
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

Editor windows also have breakpoint functions. Lines with a breakpoint set are specially marked. Breakpoints only have an effect when running under the debugger. Breakpoints for a file are saved in the user?s .idlerc directory.

-
Set Breakpoint
-
Set a breakpoint on the current line.
-
Clear Breakpoint
-
Clear the breakpoint on that line.
+
Set Breakpoint
Set a breakpoint on the current line.
+
Clear Breakpoint
Clear the breakpoint on that line.

Shell and Output windows also have the following.

-
Go to file/line
-
Same as in Debug menu.
+
Go to file/line
Same as in Debug menu.

The Shell window also has an output squeezing facility explained in the Python Shell window subsection below.

-
Squeeze
-
If the cursor is over an output line, squeeze all the output between +
Squeeze
If the cursor is over an output line, squeeze all the output between the code above and the prompt below down to a ?Squeezed text? label.
@@ -670,6 +605,9 @@

Running user codeprint or write to sys.stdout or sys.stderr, IDLE should be started in a command line window. The secondary subprocess will then be attached to that window for input and output.

+

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 -

Deprecated since version 3.4.

+

Deprecated since version 3.4.

@@ -885,7 +823,7 @@

Table of Contents

Previous topic

tkinter.scrolledtext ? Scrolled Text Widget

+ title="previous chapter">tkinter.scrolledtext ? Scrolled Text Widget

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. diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 46f0235fbfdc..d0f1e9207bb1 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -6,6 +6,8 @@ from test.support import captured_stderr import io +import sys + class RunTest(unittest.TestCase): @@ -260,5 +262,36 @@ def test_close(self): self.assertRaises(TypeError, f.close, 1) +class TestSysRecursionLimitWrappers(unittest.TestCase): + + def test_bad_setrecursionlimit_calls(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + f = sys.setrecursionlimit + self.assertRaises(TypeError, f, limit=100) + self.assertRaises(TypeError, f, 100, 1000) + self.assertRaises(ValueError, f, 0) + + def test_roundtrip(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + + # check that setting the recursion limit works + orig_reclimit = sys.getrecursionlimit() + self.addCleanup(sys.setrecursionlimit, orig_reclimit) + sys.setrecursionlimit(orig_reclimit + 3) + + # check that the new limit is returned by sys.getrecursionlimit() + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit + 3) + + def test_default_recursion_limit_preserved(self): + orig_reclimit = sys.getrecursionlimit() + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 6b3928b7bf2b..c6ed76b23a2d 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -4,10 +4,12 @@ f'''{sys.executable} -c "__import__('idlelib.run').run.main()"''' '.run' is needed because __import__ returns idlelib, not idlelib.run. """ +import functools import io import linecache import queue import sys +import textwrap import time import traceback import _thread as thread @@ -305,6 +307,64 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +RECURSIONLIMIT_DELTA = 30 +def install_recursionlimit_wrappers(): + """Install wrappers to always add 30 to the recursion limit.""" + # see: bpo-26806 + + @functools.wraps(sys.setrecursionlimit) + def setrecursionlimit(*args, **kwargs): + # mimic the original sys.setrecursionlimit()'s input handling + if kwargs: + raise TypeError( + "setrecursionlimit() takes no keyword arguments") + try: + limit, = args + except ValueError: + raise TypeError(f"setrecursionlimit() takes exactly one " + f"argument ({len(args)} given)") + if not limit > 0: + raise ValueError( + "recursion limit must be greater or equal than 1") + + return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) + + setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops. + """).strip()) + + @functools.wraps(sys.getrecursionlimit) + def getrecursionlimit(): + return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA + + getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for + the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. + """).strip()) + + # add the delta to the default recursion limit, to compensate + sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) + + sys.setrecursionlimit = setrecursionlimit + sys.getrecursionlimit = getrecursionlimit + + +def uninstall_recursionlimit_wrappers(): + """Uninstall the recursion limit wrappers from the sys module. + + IDLE only uses this for tests. Users can import run and call + this to remove the wrapping. + """ + if ( + getattr(sys.setrecursionlimit, '__wrapped__', None) and + getattr(sys.getrecursionlimit, '__wrapped__', None) + ): + sys.setrecursionlimit = sys.setrecursionlimit.__wrapped__ + sys.getrecursionlimit = sys.getrecursionlimit.__wrapped__ + sys.setrecursionlimit(sys.getrecursionlimit() - RECURSIONLIMIT_DELTA) + + class MyRPCServer(rpc.RPCServer): def handle_error(self, request, client_address): @@ -448,6 +508,8 @@ def handle(self): # sys.stdin gets changed from within IDLE's shell. See issue17838. self._keep_stdin = sys.stdin + install_recursionlimit_wrappers() + self.interp = self.get_remote_proxy("interp") rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) diff --git a/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst new file mode 100644 index 000000000000..8514bb9292fe --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst @@ -0,0 +1,4 @@ +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. From webhook-mailer at python.org Sat Jul 6 08:54:21 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 06 Jul 2019 12:54:21 -0000 Subject: [Python-checkins] bpo-26806: add 30 to the recursion limit in IDLE's shell (GH-13944) Message-ID: https://github.com/python/cpython/commit/d4af55391f56286ab8d478591017174a5a0a5ce2 commit: d4af55391f56286ab8d478591017174a5a0a5ce2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-06T05:54:17-07:00 summary: bpo-26806: add 30 to the recursion limit in IDLE's shell (GH-13944) This is done to compensate for the extra stack frames added by IDLE itself, which cause problems when setting the recursion limit to low values. This wraps sys.setrecursionlimit() and sys.getrecursionlimit() as invisibly as possible. (cherry picked from commit fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71) Co-authored-by: Tal Einat files: A Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/help.html M Lib/idlelib/idle_test/test_run.py M Lib/idlelib/run.py diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index fb886a714d74..de58f266bf5e 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -713,6 +713,10 @@ or ``print`` or ``write`` to sys.stdout or sys.stderr, IDLE should be started in a command line window. The secondary subprocess will then be attached to that window for input and output. +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 the effect of the additional stack frames. + 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. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 689539e73c12..5d4a936d63f5 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,11 @@ Released on 2019-10-20? ====================================== +bpo-26806: To compensate for stack frames added by IDLE and avoid +possible problems with low recursion limits, add 30 to limits in the +user code execution process. Subtract 30 when reporting recursion +limits to make this addition mostly transparent. + bpo-37325: Fix tab focus traversal order for help source and custom run dialogs. diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 91803fd06c8f..cee6887df68f 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -14,7 +14,7 @@ - + @@ -135,113 +135,75 @@

Menus

File menu (Shell and Editor)?

-
New File
-
Create a new file editing window.
-
Open?
-
Open an existing file with an Open dialog.
-
Recent Files
-
Open a list of recent files. Click one to open it.
-
Open Module?
-
Open an existing module (searches sys.path).
+
New File
Create a new file editing window.
+
Open?
Open an existing file with an Open dialog.
+
Recent Files
Open a list of recent files. Click one to open it.
+
Open Module?
Open an existing module (searches sys.path).
-
Class Browser
-
Show functions, classes, and methods in the current Editor file in a +
Class Browser
Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.
-
Path Browser
-
Show sys.path directories, modules, functions, classes and methods in a +
Path Browser
Show sys.path directories, modules, functions, classes and methods in a tree structure.
-
Save
-
Save the current window to the associated file, if there is one. Windows +
Save
Save the current window to the associated file, if there is one. Windows that have been changed since being opened or last saved have a * before and after the window title. If there is no associated file, do Save As instead.
-
Save As?
-
Save the current window with a Save As dialog. The file saved becomes the +
Save As?
Save the current window with a Save As dialog. The file saved becomes the new associated file for the window.
-
Save Copy As?
-
Save the current window to different file without changing the associated +
Save Copy As?
Save the current window to different file without changing the associated file.
-
Print Window
-
Print the current window to the default printer.
-
Close
-
Close the current window (ask to save if unsaved).
-
Exit
-
Close all windows and quit IDLE (ask to save unsaved windows).
+
Print Window
Print the current window to the default printer.
+
Close
Close the current window (ask to save if unsaved).
+
Exit
Close all windows and quit IDLE (ask to save unsaved windows).

Edit menu (Shell and Editor)?

-
Undo
-
Undo the last change to the current window. A maximum of 1000 changes may +
Undo
Undo the last change to the current window. A maximum of 1000 changes may be undone.
-
Redo
-
Redo the last undone change to the current window.
-
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Redo
Redo the last undone change to the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

The clipboard functions are also available in context menus.

-
Select All
-
Select the entire contents of the current window.
-
Find?
-
Open a search dialog with many options
-
Find Again
-
Repeat the last search, if there is one.
-
Find Selection
-
Search for the currently selected string, if there is one.
-
Find in Files?
-
Open a file search dialog. Put results in a new output window.
-
Replace?
-
Open a search-and-replace dialog.
-
Go to Line
-
Move cursor to the line number requested and make that line visible.
-
Show Completions
-
Open a scrollable list allowing selection of keywords and attributes. See +
Select All
Select the entire contents of the current window.
+
Find?
Open a search dialog with many options
+
Find Again
Repeat the last search, if there is one.
+
Find Selection
Search for the currently selected string, if there is one.
+
Find in Files?
Open a file search dialog. Put results in a new output window.
+
Replace?
Open a search-and-replace dialog.
+
Go to Line
Move cursor to the line number requested and make that line visible.
+
Show Completions
Open a scrollable list allowing selection of keywords and attributes. See Completions in the Editing and navigation section below.
-
Expand Word
-
Expand a prefix you have typed to match a full word in the same window; +
Expand Word
Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.
-
Show call tip
-
After an unclosed parenthesis for a function, open a small window with +
Show call tip
After an unclosed parenthesis for a function, open a small window with function parameter hints. See Calltips in the Editing and navigation section below.
-
Show surrounding parens
-
Highlight the surrounding parenthesis.
+
Show surrounding parens
Highlight the surrounding parenthesis.

Format menu (Editor window only)?

-
Indent Region
-
Shift selected lines right by the indent width (default 4 spaces).
-
Dedent Region
-
Shift selected lines left by the indent width (default 4 spaces).
-
Comment Out Region
-
Insert ## in front of selected lines.
-
Uncomment Region
-
Remove leading # or ## from selected lines.
-
Tabify Region
-
Turn leading stretches of spaces into tabs. (Note: We recommend using +
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
+
Dedent Region
Shift selected lines left by the indent width (default 4 spaces).
+
Comment Out Region
Insert ## in front of selected lines.
+
Uncomment Region
Remove leading # or ## from selected lines.
+
Tabify Region
Turn leading stretches of spaces into tabs. (Note: We recommend using 4 space blocks to indent Python code.)
-
Untabify Region
-
Turn all tabs into the correct number of spaces.
-
Toggle Tabs
-
Open a dialog to switch between indenting with spaces and tabs.
-
New Indent Width
-
Open a dialog to change indent width. The accepted default by the Python +
Untabify Region
Turn all tabs into the correct number of spaces.
+
Toggle Tabs
Open a dialog to switch between indenting with spaces and tabs.
+
New Indent Width
Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.
-
Format Paragraph
-
Reformat the current blank-line-delimited paragraph in comment block or +
Format Paragraph
Reformat the current blank-line-delimited paragraph in comment block or multiline string or selected line in a string. All lines in the paragraph will be formatted to less than N columns, where N defaults to 72.
-
Strip trailing whitespace
-
Remove trailing space and other whitespace characters after the last +
Strip trailing whitespace
Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings.
@@ -249,20 +211,17 @@

Edit menu (Shell and Editor)

Run menu (Editor window only)?

-
Python Shell
-
Open or wake up the Python Shell window.
+
Python Shell
Open or wake up the Python Shell window.
-
Check Module
-
Check the syntax of the module currently open in the Editor window. If the +
Check Module
Check the syntax of the module currently open in the Editor window. If the module has not been saved IDLE will either prompt the user to save or autosave, as selected in the General tab of the Idle Settings dialog. If there is a syntax error, the approximate location is indicated in the Editor window.
-
Run Module
-
Do Check Module. If no error, restart the shell to clean the +
Run Module
Do Check Module. If no error, restart the shell to clean the environment, then execute the module. Output is displayed in the Shell window. Note that output requires use of print or write. When execution is complete, the Shell retains focus and displays a prompt. @@ -271,8 +230,7 @@

Edit menu (Shell and Editor) -
Run? Customized
-
Same as Run Module, but run the module with customized +
Run? Customized
Same as Run Module, but run the module with customized settings. Command Line Arguments extend sys.argv as if passed on a command line. The module can be run in the Shell without restarting.

@@ -280,56 +238,44 @@

Edit menu (Shell and Editor)

Shell menu (Shell window only)?

-
View Last Restart
-
Scroll the shell window to the last Shell restart.
-
Restart Shell
-
Restart the shell to clean the environment.
-
Previous History
-
Cycle through earlier commands in history which match the current entry.
-
Next History
-
Cycle through later commands in history which match the current entry.
-
Interrupt Execution
-
Stop a running program.
+
View Last Restart
Scroll the shell window to the last Shell restart.
+
Restart Shell
Restart the shell to clean the environment.
+
Previous History
Cycle through earlier commands in history which match the current entry.
+
Next History
Cycle through later commands in history which match the current entry.
+
Interrupt Execution
Stop a running program.

Debug menu (Shell window only)?

-
Go to File/Line
-
Look on the current line. with the cursor, and the line above for a filename +
Go to File/Line
Look on the current line. with the cursor, and the line above for a filename and line number. If found, open the file if not already open, and show the line. Use this to view source lines referenced in an exception traceback and lines found by Find in Files. Also available in the context menu of the Shell window and Output windows.
-
Debugger (toggle)
-
When activated, code entered in the Shell or run from an Editor will run +
Debugger (toggle)
When activated, code entered in the Shell or run from an Editor will run under the debugger. In the Editor, breakpoints can be set with the context menu. This feature is still incomplete and somewhat experimental.
-
Stack Viewer
-
Show the stack traceback of the last exception in a tree widget, with +
Stack Viewer
Show the stack traceback of the last exception in a tree widget, with access to locals and globals.
-
Auto-open Stack Viewer
-
Toggle automatically opening the stack viewer on an unhandled exception.
+
Auto-open Stack Viewer
Toggle automatically opening the stack viewer on an unhandled exception.

Options menu (Shell and Editor)?

-
Configure IDLE
-
Open a configuration dialog and change preferences for the following: +
Configure IDLE
Open a configuration dialog and change preferences for the following: fonts, indentation, keybindings, text color themes, startup windows and size, additional help sources, and extensions. On macOS, open the configuration dialog by selecting Preferences in the application menu. For more, see Setting preferences under Help and preferences.
-
Show/Hide Code Context (Editor Window only)
-
Open a pane at the top of the edit window which shows the block context +
Show/Hide Code Context (Editor Window only)
Open a pane at the top of the edit window which shows the block context of the code which has scrolled above the top of the window. See Code Context in the Editing and Navigation section below.
-
Zoom/Restore Height
-
Toggles the window between normal size and maximum height. The initial size +
Zoom/Restore Height
Toggles the window between normal size and maximum height. The initial size defaults to 40 lines by 80 chars unless changed on the General tab of the Configure IDLE dialog. The maximum height for a screen is determined by momentarily maximizing a window the first time one is zoomed on the screen. @@ -345,16 +291,12 @@

Window menu (Shell and Editor)

Help menu (Shell and Editor)?

-
About IDLE
-
Display version, copyright, license, credits, and more.
-
IDLE Help
-
Display this IDLE document, detailing the menu options, basic editing and +
About IDLE
Display version, copyright, license, credits, and more.
+
IDLE Help
Display this IDLE document, detailing the menu options, basic editing and navigation, and other tips.
-
Python Docs
-
Access local Python documentation, if installed, or start a web browser +
Python Docs
Access local Python documentation, if installed, or start a web browser and open docs.python.org showing the latest Python documentation.
-
Turtle Demo
-
Run the turtledemo module with example Python code and turtle drawings.
+
Turtle Demo
Run the turtledemo module with example Python code and turtle drawings.

Additional help sources may be added here with the Configure IDLE dialog under the General tab. See the Help sources subsection below @@ -365,32 +307,25 @@

Help menu (Shell and Editor) -
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

Editor windows also have breakpoint functions. Lines with a breakpoint set are specially marked. Breakpoints only have an effect when running under the debugger. Breakpoints for a file are saved in the user?s .idlerc directory.

-
Set Breakpoint
-
Set a breakpoint on the current line.
-
Clear Breakpoint
-
Clear the breakpoint on that line.
+
Set Breakpoint
Set a breakpoint on the current line.
+
Clear Breakpoint
Clear the breakpoint on that line.

Shell and Output windows also have the following.

-
Go to file/line
-
Same as in Debug menu.
+
Go to file/line
Same as in Debug menu.

The Shell window also has an output squeezing facility explained in the Python Shell window subsection below.

-
Squeeze
-
If the cursor is over an output line, squeeze all the output between +
Squeeze
If the cursor is over an output line, squeeze all the output between the code above and the prompt below down to a ?Squeezed text? label.
@@ -670,6 +605,9 @@

Running user codeprint or write to sys.stdout or sys.stderr, IDLE should be started in a command line window. The secondary subprocess will then be attached to that window for input and output.

+

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 -

Deprecated since version 3.4.

+

Deprecated since version 3.4.

@@ -885,7 +823,7 @@

Table of Contents

Previous topic

tkinter.scrolledtext ? Scrolled Text Widget

+ title="previous chapter">tkinter.scrolledtext ? Scrolled Text Widget

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. diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 46f0235fbfdc..d0f1e9207bb1 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -6,6 +6,8 @@ from test.support import captured_stderr import io +import sys + class RunTest(unittest.TestCase): @@ -260,5 +262,36 @@ def test_close(self): self.assertRaises(TypeError, f.close, 1) +class TestSysRecursionLimitWrappers(unittest.TestCase): + + def test_bad_setrecursionlimit_calls(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + f = sys.setrecursionlimit + self.assertRaises(TypeError, f, limit=100) + self.assertRaises(TypeError, f, 100, 1000) + self.assertRaises(ValueError, f, 0) + + def test_roundtrip(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + + # check that setting the recursion limit works + orig_reclimit = sys.getrecursionlimit() + self.addCleanup(sys.setrecursionlimit, orig_reclimit) + sys.setrecursionlimit(orig_reclimit + 3) + + # check that the new limit is returned by sys.getrecursionlimit() + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit + 3) + + def test_default_recursion_limit_preserved(self): + orig_reclimit = sys.getrecursionlimit() + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 6b3928b7bf2b..c6ed76b23a2d 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -4,10 +4,12 @@ f'''{sys.executable} -c "__import__('idlelib.run').run.main()"''' '.run' is needed because __import__ returns idlelib, not idlelib.run. """ +import functools import io import linecache import queue import sys +import textwrap import time import traceback import _thread as thread @@ -305,6 +307,64 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +RECURSIONLIMIT_DELTA = 30 +def install_recursionlimit_wrappers(): + """Install wrappers to always add 30 to the recursion limit.""" + # see: bpo-26806 + + @functools.wraps(sys.setrecursionlimit) + def setrecursionlimit(*args, **kwargs): + # mimic the original sys.setrecursionlimit()'s input handling + if kwargs: + raise TypeError( + "setrecursionlimit() takes no keyword arguments") + try: + limit, = args + except ValueError: + raise TypeError(f"setrecursionlimit() takes exactly one " + f"argument ({len(args)} given)") + if not limit > 0: + raise ValueError( + "recursion limit must be greater or equal than 1") + + return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) + + setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops. + """).strip()) + + @functools.wraps(sys.getrecursionlimit) + def getrecursionlimit(): + return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA + + getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for + the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. + """).strip()) + + # add the delta to the default recursion limit, to compensate + sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) + + sys.setrecursionlimit = setrecursionlimit + sys.getrecursionlimit = getrecursionlimit + + +def uninstall_recursionlimit_wrappers(): + """Uninstall the recursion limit wrappers from the sys module. + + IDLE only uses this for tests. Users can import run and call + this to remove the wrapping. + """ + if ( + getattr(sys.setrecursionlimit, '__wrapped__', None) and + getattr(sys.getrecursionlimit, '__wrapped__', None) + ): + sys.setrecursionlimit = sys.setrecursionlimit.__wrapped__ + sys.getrecursionlimit = sys.getrecursionlimit.__wrapped__ + sys.setrecursionlimit(sys.getrecursionlimit() - RECURSIONLIMIT_DELTA) + + class MyRPCServer(rpc.RPCServer): def handle_error(self, request, client_address): @@ -448,6 +508,8 @@ def handle(self): # sys.stdin gets changed from within IDLE's shell. See issue17838. self._keep_stdin = sys.stdin + install_recursionlimit_wrappers() + self.interp = self.get_remote_proxy("interp") rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) diff --git a/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst new file mode 100644 index 000000000000..8514bb9292fe --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst @@ -0,0 +1,4 @@ +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. From webhook-mailer at python.org Sat Jul 6 08:56:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 06 Jul 2019 12:56:14 -0000 Subject: [Python-checkins] bpo-26806: add 30 to the recursion limit in IDLE's shell (GH-13944) Message-ID: https://github.com/python/cpython/commit/d666217b26c373784761e3a84f243f02682bccb1 commit: d666217b26c373784761e3a84f243f02682bccb1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-06T05:56:10-07:00 summary: bpo-26806: add 30 to the recursion limit in IDLE's shell (GH-13944) This is done to compensate for the extra stack frames added by IDLE itself, which cause problems when setting the recursion limit to low values. This wraps sys.setrecursionlimit() and sys.getrecursionlimit() as invisibly as possible. (cherry picked from commit fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71) Co-authored-by: Tal Einat files: A Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/help.html M Lib/idlelib/idle_test/test_run.py M Lib/idlelib/run.py diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index fb886a714d74..de58f266bf5e 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -713,6 +713,10 @@ or ``print`` or ``write`` to sys.stdout or sys.stderr, IDLE should be started in a command line window. The secondary subprocess will then be attached to that window for input and output. +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 the effect of the additional stack frames. + 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. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 834646f7f776..4fad45b2de9c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,11 @@ Released on 2019-06-24? ====================================== +bpo-26806: To compensate for stack frames added by IDLE and avoid +possible problems with low recursion limits, add 30 to limits in the +user code execution process. Subtract 30 when reporting recursion +limits to make this addition mostly transparent. + bpo-37325: Fix tab focus traversal order for help source and custom run dialogs. diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 91803fd06c8f..cee6887df68f 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -14,7 +14,7 @@ - + @@ -135,113 +135,75 @@

Menus

File menu (Shell and Editor)?

-
New File
-
Create a new file editing window.
-
Open?
-
Open an existing file with an Open dialog.
-
Recent Files
-
Open a list of recent files. Click one to open it.
-
Open Module?
-
Open an existing module (searches sys.path).
+
New File
Create a new file editing window.
+
Open?
Open an existing file with an Open dialog.
+
Recent Files
Open a list of recent files. Click one to open it.
+
Open Module?
Open an existing module (searches sys.path).
-
Class Browser
-
Show functions, classes, and methods in the current Editor file in a +
Class Browser
Show functions, classes, and methods in the current Editor file in a tree structure. In the shell, open a module first.
-
Path Browser
-
Show sys.path directories, modules, functions, classes and methods in a +
Path Browser
Show sys.path directories, modules, functions, classes and methods in a tree structure.
-
Save
-
Save the current window to the associated file, if there is one. Windows +
Save
Save the current window to the associated file, if there is one. Windows that have been changed since being opened or last saved have a * before and after the window title. If there is no associated file, do Save As instead.
-
Save As?
-
Save the current window with a Save As dialog. The file saved becomes the +
Save As?
Save the current window with a Save As dialog. The file saved becomes the new associated file for the window.
-
Save Copy As?
-
Save the current window to different file without changing the associated +
Save Copy As?
Save the current window to different file without changing the associated file.
-
Print Window
-
Print the current window to the default printer.
-
Close
-
Close the current window (ask to save if unsaved).
-
Exit
-
Close all windows and quit IDLE (ask to save unsaved windows).
+
Print Window
Print the current window to the default printer.
+
Close
Close the current window (ask to save if unsaved).
+
Exit
Close all windows and quit IDLE (ask to save unsaved windows).

Edit menu (Shell and Editor)?

-
Undo
-
Undo the last change to the current window. A maximum of 1000 changes may +
Undo
Undo the last change to the current window. A maximum of 1000 changes may be undone.
-
Redo
-
Redo the last undone change to the current window.
-
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Redo
Redo the last undone change to the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

The clipboard functions are also available in context menus.

-
Select All
-
Select the entire contents of the current window.
-
Find?
-
Open a search dialog with many options
-
Find Again
-
Repeat the last search, if there is one.
-
Find Selection
-
Search for the currently selected string, if there is one.
-
Find in Files?
-
Open a file search dialog. Put results in a new output window.
-
Replace?
-
Open a search-and-replace dialog.
-
Go to Line
-
Move cursor to the line number requested and make that line visible.
-
Show Completions
-
Open a scrollable list allowing selection of keywords and attributes. See +
Select All
Select the entire contents of the current window.
+
Find?
Open a search dialog with many options
+
Find Again
Repeat the last search, if there is one.
+
Find Selection
Search for the currently selected string, if there is one.
+
Find in Files?
Open a file search dialog. Put results in a new output window.
+
Replace?
Open a search-and-replace dialog.
+
Go to Line
Move cursor to the line number requested and make that line visible.
+
Show Completions
Open a scrollable list allowing selection of keywords and attributes. See Completions in the Editing and navigation section below.
-
Expand Word
-
Expand a prefix you have typed to match a full word in the same window; +
Expand Word
Expand a prefix you have typed to match a full word in the same window; repeat to get a different expansion.
-
Show call tip
-
After an unclosed parenthesis for a function, open a small window with +
Show call tip
After an unclosed parenthesis for a function, open a small window with function parameter hints. See Calltips in the Editing and navigation section below.
-
Show surrounding parens
-
Highlight the surrounding parenthesis.
+
Show surrounding parens
Highlight the surrounding parenthesis.

Format menu (Editor window only)?

-
Indent Region
-
Shift selected lines right by the indent width (default 4 spaces).
-
Dedent Region
-
Shift selected lines left by the indent width (default 4 spaces).
-
Comment Out Region
-
Insert ## in front of selected lines.
-
Uncomment Region
-
Remove leading # or ## from selected lines.
-
Tabify Region
-
Turn leading stretches of spaces into tabs. (Note: We recommend using +
Indent Region
Shift selected lines right by the indent width (default 4 spaces).
+
Dedent Region
Shift selected lines left by the indent width (default 4 spaces).
+
Comment Out Region
Insert ## in front of selected lines.
+
Uncomment Region
Remove leading # or ## from selected lines.
+
Tabify Region
Turn leading stretches of spaces into tabs. (Note: We recommend using 4 space blocks to indent Python code.)
-
Untabify Region
-
Turn all tabs into the correct number of spaces.
-
Toggle Tabs
-
Open a dialog to switch between indenting with spaces and tabs.
-
New Indent Width
-
Open a dialog to change indent width. The accepted default by the Python +
Untabify Region
Turn all tabs into the correct number of spaces.
+
Toggle Tabs
Open a dialog to switch between indenting with spaces and tabs.
+
New Indent Width
Open a dialog to change indent width. The accepted default by the Python community is 4 spaces.
-
Format Paragraph
-
Reformat the current blank-line-delimited paragraph in comment block or +
Format Paragraph
Reformat the current blank-line-delimited paragraph in comment block or multiline string or selected line in a string. All lines in the paragraph will be formatted to less than N columns, where N defaults to 72.
-
Strip trailing whitespace
-
Remove trailing space and other whitespace characters after the last +
Strip trailing whitespace
Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, including lines within multiline strings.
@@ -249,20 +211,17 @@

Edit menu (Shell and Editor)

Run menu (Editor window only)?

-
Python Shell
-
Open or wake up the Python Shell window.
+
Python Shell
Open or wake up the Python Shell window.
-
Check Module
-
Check the syntax of the module currently open in the Editor window. If the +
Check Module
Check the syntax of the module currently open in the Editor window. If the module has not been saved IDLE will either prompt the user to save or autosave, as selected in the General tab of the Idle Settings dialog. If there is a syntax error, the approximate location is indicated in the Editor window.
-
Run Module
-
Do Check Module. If no error, restart the shell to clean the +
Run Module
Do Check Module. If no error, restart the shell to clean the environment, then execute the module. Output is displayed in the Shell window. Note that output requires use of print or write. When execution is complete, the Shell retains focus and displays a prompt. @@ -271,8 +230,7 @@

Edit menu (Shell and Editor) -
Run? Customized
-
Same as Run Module, but run the module with customized +
Run? Customized
Same as Run Module, but run the module with customized settings. Command Line Arguments extend sys.argv as if passed on a command line. The module can be run in the Shell without restarting.

@@ -280,56 +238,44 @@

Edit menu (Shell and Editor)

Shell menu (Shell window only)?

-
View Last Restart
-
Scroll the shell window to the last Shell restart.
-
Restart Shell
-
Restart the shell to clean the environment.
-
Previous History
-
Cycle through earlier commands in history which match the current entry.
-
Next History
-
Cycle through later commands in history which match the current entry.
-
Interrupt Execution
-
Stop a running program.
+
View Last Restart
Scroll the shell window to the last Shell restart.
+
Restart Shell
Restart the shell to clean the environment.
+
Previous History
Cycle through earlier commands in history which match the current entry.
+
Next History
Cycle through later commands in history which match the current entry.
+
Interrupt Execution
Stop a running program.

Debug menu (Shell window only)?

-
Go to File/Line
-
Look on the current line. with the cursor, and the line above for a filename +
Go to File/Line
Look on the current line. with the cursor, and the line above for a filename and line number. If found, open the file if not already open, and show the line. Use this to view source lines referenced in an exception traceback and lines found by Find in Files. Also available in the context menu of the Shell window and Output windows.
-
Debugger (toggle)
-
When activated, code entered in the Shell or run from an Editor will run +
Debugger (toggle)
When activated, code entered in the Shell or run from an Editor will run under the debugger. In the Editor, breakpoints can be set with the context menu. This feature is still incomplete and somewhat experimental.
-
Stack Viewer
-
Show the stack traceback of the last exception in a tree widget, with +
Stack Viewer
Show the stack traceback of the last exception in a tree widget, with access to locals and globals.
-
Auto-open Stack Viewer
-
Toggle automatically opening the stack viewer on an unhandled exception.
+
Auto-open Stack Viewer
Toggle automatically opening the stack viewer on an unhandled exception.

Options menu (Shell and Editor)?

-
Configure IDLE
-
Open a configuration dialog and change preferences for the following: +
Configure IDLE
Open a configuration dialog and change preferences for the following: fonts, indentation, keybindings, text color themes, startup windows and size, additional help sources, and extensions. On macOS, open the configuration dialog by selecting Preferences in the application menu. For more, see Setting preferences under Help and preferences.
-
Show/Hide Code Context (Editor Window only)
-
Open a pane at the top of the edit window which shows the block context +
Show/Hide Code Context (Editor Window only)
Open a pane at the top of the edit window which shows the block context of the code which has scrolled above the top of the window. See Code Context in the Editing and Navigation section below.
-
Zoom/Restore Height
-
Toggles the window between normal size and maximum height. The initial size +
Zoom/Restore Height
Toggles the window between normal size and maximum height. The initial size defaults to 40 lines by 80 chars unless changed on the General tab of the Configure IDLE dialog. The maximum height for a screen is determined by momentarily maximizing a window the first time one is zoomed on the screen. @@ -345,16 +291,12 @@

Window menu (Shell and Editor)

Help menu (Shell and Editor)?

-
About IDLE
-
Display version, copyright, license, credits, and more.
-
IDLE Help
-
Display this IDLE document, detailing the menu options, basic editing and +
About IDLE
Display version, copyright, license, credits, and more.
+
IDLE Help
Display this IDLE document, detailing the menu options, basic editing and navigation, and other tips.
-
Python Docs
-
Access local Python documentation, if installed, or start a web browser +
Python Docs
Access local Python documentation, if installed, or start a web browser and open docs.python.org showing the latest Python documentation.
-
Turtle Demo
-
Run the turtledemo module with example Python code and turtle drawings.
+
Turtle Demo
Run the turtledemo module with example Python code and turtle drawings.

Additional help sources may be added here with the Configure IDLE dialog under the General tab. See the Help sources subsection below @@ -365,32 +307,25 @@

Help menu (Shell and Editor) -
Cut
-
Copy selection into the system-wide clipboard; then delete the selection.
-
Copy
-
Copy selection into the system-wide clipboard.
-
Paste
-
Insert contents of the system-wide clipboard into the current window.
+
Cut
Copy selection into the system-wide clipboard; then delete the selection.
+
Copy
Copy selection into the system-wide clipboard.
+
Paste
Insert contents of the system-wide clipboard into the current window.

Editor windows also have breakpoint functions. Lines with a breakpoint set are specially marked. Breakpoints only have an effect when running under the debugger. Breakpoints for a file are saved in the user?s .idlerc directory.

-
Set Breakpoint
-
Set a breakpoint on the current line.
-
Clear Breakpoint
-
Clear the breakpoint on that line.
+
Set Breakpoint
Set a breakpoint on the current line.
+
Clear Breakpoint
Clear the breakpoint on that line.

Shell and Output windows also have the following.

-
Go to file/line
-
Same as in Debug menu.
+
Go to file/line
Same as in Debug menu.

The Shell window also has an output squeezing facility explained in the Python Shell window subsection below.

-
Squeeze
-
If the cursor is over an output line, squeeze all the output between +
Squeeze
If the cursor is over an output line, squeeze all the output between the code above and the prompt below down to a ?Squeezed text? label.
@@ -670,6 +605,9 @@

Running user codeprint or write to sys.stdout or sys.stderr, IDLE should be started in a command line window. The secondary subprocess will then be attached to that window for input and output.

+

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 -

Deprecated since version 3.4.

+

Deprecated since version 3.4.

@@ -885,7 +823,7 @@

Table of Contents

Previous topic

tkinter.scrolledtext ? Scrolled Text Widget

+ title="previous chapter">tkinter.scrolledtext ? Scrolled Text Widget

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. diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index 46f0235fbfdc..d0f1e9207bb1 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -6,6 +6,8 @@ from test.support import captured_stderr import io +import sys + class RunTest(unittest.TestCase): @@ -260,5 +262,36 @@ def test_close(self): self.assertRaises(TypeError, f.close, 1) +class TestSysRecursionLimitWrappers(unittest.TestCase): + + def test_bad_setrecursionlimit_calls(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + f = sys.setrecursionlimit + self.assertRaises(TypeError, f, limit=100) + self.assertRaises(TypeError, f, 100, 1000) + self.assertRaises(ValueError, f, 0) + + def test_roundtrip(self): + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + + # check that setting the recursion limit works + orig_reclimit = sys.getrecursionlimit() + self.addCleanup(sys.setrecursionlimit, orig_reclimit) + sys.setrecursionlimit(orig_reclimit + 3) + + # check that the new limit is returned by sys.getrecursionlimit() + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit + 3) + + def test_default_recursion_limit_preserved(self): + orig_reclimit = sys.getrecursionlimit() + run.install_recursionlimit_wrappers() + self.addCleanup(run.uninstall_recursionlimit_wrappers) + new_reclimit = sys.getrecursionlimit() + self.assertEqual(new_reclimit, orig_reclimit) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 6b3928b7bf2b..c6ed76b23a2d 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -4,10 +4,12 @@ f'''{sys.executable} -c "__import__('idlelib.run').run.main()"''' '.run' is needed because __import__ returns idlelib, not idlelib.run. """ +import functools import io import linecache import queue import sys +import textwrap import time import traceback import _thread as thread @@ -305,6 +307,64 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +RECURSIONLIMIT_DELTA = 30 +def install_recursionlimit_wrappers(): + """Install wrappers to always add 30 to the recursion limit.""" + # see: bpo-26806 + + @functools.wraps(sys.setrecursionlimit) + def setrecursionlimit(*args, **kwargs): + # mimic the original sys.setrecursionlimit()'s input handling + if kwargs: + raise TypeError( + "setrecursionlimit() takes no keyword arguments") + try: + limit, = args + except ValueError: + raise TypeError(f"setrecursionlimit() takes exactly one " + f"argument ({len(args)} given)") + if not limit > 0: + raise ValueError( + "recursion limit must be greater or equal than 1") + + return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) + + setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops. + """).strip()) + + @functools.wraps(sys.getrecursionlimit) + def getrecursionlimit(): + return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA + + getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for + the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. + """).strip()) + + # add the delta to the default recursion limit, to compensate + sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) + + sys.setrecursionlimit = setrecursionlimit + sys.getrecursionlimit = getrecursionlimit + + +def uninstall_recursionlimit_wrappers(): + """Uninstall the recursion limit wrappers from the sys module. + + IDLE only uses this for tests. Users can import run and call + this to remove the wrapping. + """ + if ( + getattr(sys.setrecursionlimit, '__wrapped__', None) and + getattr(sys.getrecursionlimit, '__wrapped__', None) + ): + sys.setrecursionlimit = sys.setrecursionlimit.__wrapped__ + sys.getrecursionlimit = sys.getrecursionlimit.__wrapped__ + sys.setrecursionlimit(sys.getrecursionlimit() - RECURSIONLIMIT_DELTA) + + class MyRPCServer(rpc.RPCServer): def handle_error(self, request, client_address): @@ -448,6 +508,8 @@ def handle(self): # sys.stdin gets changed from within IDLE's shell. See issue17838. self._keep_stdin = sys.stdin + install_recursionlimit_wrappers() + self.interp = self.get_remote_proxy("interp") rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) diff --git a/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst new file mode 100644 index 000000000000..8514bb9292fe --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst @@ -0,0 +1,4 @@ +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. From webhook-mailer at python.org Sat Jul 6 17:40:31 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 21:40:31 -0000 Subject: [Python-checkins] bpo-37487: Fix PyList_GetItem index description. (GH-14623) Message-ID: https://github.com/python/cpython/commit/f8709e804d16ec5d44b1d2f00d59a0f78df7b792 commit: f8709e804d16ec5d44b1d2f00d59a0f78df7b792 branch: master author: Terry Jan Reedy committer: GitHub date: 2019-07-06T17:40:27-04:00 summary: bpo-37487: Fix PyList_GetItem index description. (GH-14623) 0 is a legal index. files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst M Doc/c-api/list.rst diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index 279783a243a1..dc9026605be3 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -59,9 +59,9 @@ List Objects .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The - position must be positive, indexing from the end of the list is not - supported. If *index* is out of bounds, return *NULL* and set an - :exc:`IndexError` exception. + position must be non-negative; indexing from the end of the list is not + supported. If *index* is out of bounds (<0 or >=len(list)), + return *NULL* and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst new file mode 100644 index 000000000000..605d08c3c040 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst @@ -0,0 +1 @@ +Fix PyList_GetItem index description to include 0. From webhook-mailer at python.org Sat Jul 6 17:55:00 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 21:55:00 -0000 Subject: [Python-checkins] bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14624) Message-ID: https://github.com/python/cpython/commit/ad3720359faa933d04bde3d3222fd54e73ee7feb commit: ad3720359faa933d04bde3d3222fd54e73ee7feb branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T17:54:56-04:00 summary: bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14624) 0 is a legal index. (cherry picked from commit f8709e804d16ec5d44b1d2f00d59a0f78df7b792) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst M Doc/c-api/list.rst diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index 279783a243a1..dc9026605be3 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -59,9 +59,9 @@ List Objects .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The - position must be positive, indexing from the end of the list is not - supported. If *index* is out of bounds, return *NULL* and set an - :exc:`IndexError` exception. + position must be non-negative; indexing from the end of the list is not + supported. If *index* is out of bounds (<0 or >=len(list)), + return *NULL* and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst new file mode 100644 index 000000000000..605d08c3c040 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst @@ -0,0 +1 @@ +Fix PyList_GetItem index description to include 0. From webhook-mailer at python.org Sat Jul 6 17:55:23 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 21:55:23 -0000 Subject: [Python-checkins] bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14625) Message-ID: https://github.com/python/cpython/commit/9c930d076a7225694b369d30636a29acb556c2be commit: 9c930d076a7225694b369d30636a29acb556c2be branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T17:55:19-04:00 summary: bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14625) 0 is a legal index. (cherry picked from commit f8709e804d16ec5d44b1d2f00d59a0f78df7b792) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst M Doc/c-api/list.rst diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index 5b263a7b1cdf..a5cd634a454a 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -59,9 +59,9 @@ List Objects .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The - position must be positive, indexing from the end of the list is not - supported. If *index* is out of bounds, return *NULL* and set an - :exc:`IndexError` exception. + position must be non-negative; indexing from the end of the list is not + supported. If *index* is out of bounds (<0 or >=len(list)), + return *NULL* and set an :exc:`IndexError` exception. .. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst new file mode 100644 index 000000000000..605d08c3c040 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst @@ -0,0 +1 @@ +Fix PyList_GetItem index description to include 0. From webhook-mailer at python.org Sat Jul 6 17:55:45 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 21:55:45 -0000 Subject: [Python-checkins] bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14626) Message-ID: https://github.com/python/cpython/commit/dd3862e167d573b6e9a3348c365229ca958d1f1f commit: dd3862e167d573b6e9a3348c365229ca958d1f1f branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T17:55:41-04:00 summary: bpo-37487: Fix PyList_GetItem index description. (GH-14623) (GH-14626) 0 is a legal index. (cherry picked from commit f8709e804d16ec5d44b1d2f00d59a0f78df7b792) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst M Doc/c-api/list.rst diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index 0aed0f3e8899..a5e4a45492b6 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -76,9 +76,9 @@ List Objects .. c:function:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) Return the object at position *index* in the list pointed to by *list*. The - position must be positive, indexing from the end of the list is not - supported. If *index* is out of bounds, return *NULL* and set an - :exc:`IndexError` exception. + position must be non-negative; indexing from the end of the list is not + supported. If *index* is out of bounds (<0 or >=len(list)), + return *NULL* and set an :exc:`IndexError` exception. .. versionchanged:: 2.5 This function used an :c:type:`int` for *index*. This might require diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst new file mode 100644 index 000000000000..605d08c3c040 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst @@ -0,0 +1 @@ +Fix PyList_GetItem index description to include 0. From webhook-mailer at python.org Sat Jul 6 18:13:07 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 22:13:07 -0000 Subject: [Python-checkins] bpo-37456: Slash ('/') is now part of syntax. (GH-14627) Message-ID: https://github.com/python/cpython/commit/6f2a8c08573c71b78d2f6e2bfaf31641a0cd092b commit: 6f2a8c08573c71b78d2f6e2bfaf31641a0cd092b branch: master author: Terry Jan Reedy committer: GitHub date: 2019-07-06T18:13:02-04:00 summary: bpo-37456: Slash ('/') is now part of syntax. (GH-14627) files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst M Doc/faq/programming.rst diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index a00c6a053ef1..a36fa4aefe88 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -800,10 +800,6 @@ an error:: File "", line 1, in TypeError: pow() takes no keyword arguments -Note that as of this writing this is only documentational and no valid syntax -in Python, although there is :pep:`570`, which proposes a syntax for -position-only parameters in Python. - Numbers and strings =================== diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst new file mode 100644 index 000000000000..4d158733b0ea --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst @@ -0,0 +1 @@ +Slash ('/') is now part of syntax. From webhook-mailer at python.org Sat Jul 6 18:25:50 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sat, 06 Jul 2019 22:25:50 -0000 Subject: [Python-checkins] bpo-37456: Slash ('/') is now part of syntax. (GH-14627) (GH-14628) Message-ID: https://github.com/python/cpython/commit/90631f9bc5f78ec6cdc2096d5c5ae26e41e5f150 commit: 90631f9bc5f78ec6cdc2096d5c5ae26e41e5f150 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T18:25:47-04:00 summary: bpo-37456: Slash ('/') is now part of syntax. (GH-14627) (GH-14628) (cherry picked from commit 6f2a8c08573c71b78d2f6e2bfaf31641a0cd092b) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst M Doc/faq/programming.rst diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index a00c6a053ef1..a36fa4aefe88 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -800,10 +800,6 @@ an error:: File "", line 1, in TypeError: pow() takes no keyword arguments -Note that as of this writing this is only documentational and no valid syntax -in Python, although there is :pep:`570`, which proposes a syntax for -position-only parameters in Python. - Numbers and strings =================== diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst new file mode 100644 index 000000000000..4d158733b0ea --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst @@ -0,0 +1 @@ +Slash ('/') is now part of syntax. From webhook-mailer at python.org Sat Jul 6 21:20:20 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sun, 07 Jul 2019 01:20:20 -0000 Subject: [Python-checkins] bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) Message-ID: https://github.com/python/cpython/commit/0717b4d9b3899c5c2ca13031e4ff619a15a4d368 commit: 0717b4d9b3899c5c2ca13031e4ff619a15a4d368 branch: master author: Kyle Stanley committer: Terry Jan Reedy date: 2019-07-06T21:20:15-04:00 summary: bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) files: A Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6e8df88cf052..760c05c6e52d 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1599,6 +1599,9 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. + This function can raise :exc:`OSError` subclasses such as + :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst new file mode 100644 index 000000000000..55b136621762 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst @@ -0,0 +1 @@ +Added possible exceptions to the description of os.chdir(). \ No newline at end of file From webhook-mailer at python.org Sat Jul 6 22:18:53 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sun, 07 Jul 2019 02:18:53 -0000 Subject: [Python-checkins] bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) (GH-14629) Message-ID: https://github.com/python/cpython/commit/4e6bfc4c605d92d2395fbcded9cf45cdd1ced810 commit: 4e6bfc4c605d92d2395fbcded9cf45cdd1ced810 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T22:18:50-04:00 summary: bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) (GH-14629) (cherry picked from commit 0717b4d9b3899c5c2ca13031e4ff619a15a4d368) Co-authored-by: Kyle Stanley files: A Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6e8df88cf052..760c05c6e52d 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1599,6 +1599,9 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. + This function can raise :exc:`OSError` subclasses such as + :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst new file mode 100644 index 000000000000..55b136621762 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst @@ -0,0 +1 @@ +Added possible exceptions to the description of os.chdir(). \ No newline at end of file From webhook-mailer at python.org Sat Jul 6 22:19:11 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sun, 07 Jul 2019 02:19:11 -0000 Subject: [Python-checkins] bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) (GH-14630) Message-ID: https://github.com/python/cpython/commit/1dd65075955337183ba2f78cb11a1eec2466dc74 commit: 1dd65075955337183ba2f78cb11a1eec2466dc74 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-06T22:19:08-04:00 summary: bpo-37478: Specify possible exceptions for os.chdir() (GH-14611) (GH-14630) (cherry picked from commit 0717b4d9b3899c5c2ca13031e4ff619a15a4d368) Co-authored-by: Kyle Stanley files: A Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 63d118d40f9a..856ef2b2dbe4 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1566,6 +1566,9 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. + This function can raise :exc:`OSError` subclasses such as + :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. + .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst new file mode 100644 index 000000000000..55b136621762 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst @@ -0,0 +1 @@ +Added possible exceptions to the description of os.chdir(). \ No newline at end of file From webhook-mailer at python.org Sat Jul 6 22:44:04 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sun, 07 Jul 2019 02:44:04 -0000 Subject: [Python-checkins] bpo-37478: Add missing 'and'. (GH-14631) Message-ID: https://github.com/python/cpython/commit/a9b40e4546ca631e5ab41376b5b72e8f296f557d commit: a9b40e4546ca631e5ab41376b5b72e8f296f557d branch: master author: Terry Jan Reedy committer: GitHub date: 2019-07-06T22:44:01-04:00 summary: bpo-37478: Add missing 'and'. (GH-14631) files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 760c05c6e52d..519d5581603b 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1599,7 +1599,7 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. - This function can raise :exc:`OSError` subclasses such as + This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. .. versionadded:: 3.3 From webhook-mailer at python.org Sat Jul 6 22:49:42 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 07 Jul 2019 02:49:42 -0000 Subject: [Python-checkins] bpo-37478: Add missing 'and'. (GH-14631) Message-ID: https://github.com/python/cpython/commit/e841a54206c65770aeb2b936cdc830dd4ed8bf9e commit: e841a54206c65770aeb2b936cdc830dd4ed8bf9e branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-06T19:49:39-07:00 summary: bpo-37478: Add missing 'and'. (GH-14631) (cherry picked from commit a9b40e4546ca631e5ab41376b5b72e8f296f557d) Co-authored-by: Terry Jan Reedy files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 856ef2b2dbe4..24f14480ae04 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1566,7 +1566,7 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. - This function can raise :exc:`OSError` subclasses such as + This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. .. versionadded:: 3.3 From webhook-mailer at python.org Sat Jul 6 22:50:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 07 Jul 2019 02:50:52 -0000 Subject: [Python-checkins] bpo-37478: Add missing 'and'. (GH-14631) Message-ID: https://github.com/python/cpython/commit/e414aa9cb002427a39dfd157cdad156336f93ca9 commit: e414aa9cb002427a39dfd157cdad156336f93ca9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-06T19:50:48-07:00 summary: bpo-37478: Add missing 'and'. (GH-14631) (cherry picked from commit a9b40e4546ca631e5ab41376b5b72e8f296f557d) Co-authored-by: Terry Jan Reedy files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 760c05c6e52d..519d5581603b 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1599,7 +1599,7 @@ features: This function can support :ref:`specifying a file descriptor `. The descriptor must refer to an opened directory, not an open file. - This function can raise :exc:`OSError` subclasses such as + This function can raise :exc:`OSError` and subclasses such as :exc:`FileNotFoundError`, :exc:`PermissionError`, and :exc:`NotADirectoryError`. .. versionadded:: 3.3 From webhook-mailer at python.org Sun Jul 7 11:40:31 2019 From: webhook-mailer at python.org (Xiang Zhang) Date: Sun, 07 Jul 2019 15:40:31 -0000 Subject: [Python-checkins] bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) Message-ID: https://github.com/python/cpython/commit/f6cdd3ff687ebbf8209d793a18a042ea495c4aeb commit: f6cdd3ff687ebbf8209d793a18a042ea495c4aeb branch: master author: Hai Shi committer: Xiang Zhang date: 2019-07-07T23:40:07+08:00 summary: bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 2c57cc7ec427..680703d4483f 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -576,7 +576,7 @@ Here is a simple example of a POINT structure, which contains two integers named >>> POINT(1, 2, 3) Traceback (most recent call last): File "", line 1, in - ValueError: too many initializers + TypeError: too many initializers >>> You can, however, build much more complicated structures. A structure can From webhook-mailer at python.org Sun Jul 7 11:46:06 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 07 Jul 2019 15:46:06 -0000 Subject: [Python-checkins] bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) Message-ID: https://github.com/python/cpython/commit/bc0a6ced30267d4e21e7566bfd6d14b30d6d1604 commit: bc0a6ced30267d4e21e7566bfd6d14b30d6d1604 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-07T08:45:59-07:00 summary: bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) (cherry picked from commit f6cdd3ff687ebbf8209d793a18a042ea495c4aeb) Co-authored-by: Hai Shi files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 60a2ec1c5e89..46a9d23ac392 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -576,7 +576,7 @@ Here is a simple example of a POINT structure, which contains two integers named >>> POINT(1, 2, 3) Traceback (most recent call last): File "", line 1, in - ValueError: too many initializers + TypeError: too many initializers >>> You can, however, build much more complicated structures. A structure can From webhook-mailer at python.org Sun Jul 7 11:46:50 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 07 Jul 2019 15:46:50 -0000 Subject: [Python-checkins] bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) Message-ID: https://github.com/python/cpython/commit/3f7d0c9665ca546bb0073376cb83e31dd13b48d9 commit: 3f7d0c9665ca546bb0073376cb83e31dd13b48d9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-07T08:46:46-07:00 summary: bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) (cherry picked from commit f6cdd3ff687ebbf8209d793a18a042ea495c4aeb) Co-authored-by: Hai Shi files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 2c57cc7ec427..680703d4483f 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -576,7 +576,7 @@ Here is a simple example of a POINT structure, which contains two integers named >>> POINT(1, 2, 3) Traceback (most recent call last): File "", line 1, in - ValueError: too many initializers + TypeError: too many initializers >>> You can, however, build much more complicated structures. A structure can From webhook-mailer at python.org Sun Jul 7 11:59:18 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 07 Jul 2019 15:59:18 -0000 Subject: [Python-checkins] bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) Message-ID: https://github.com/python/cpython/commit/00bf4d64ecb01027be40c32d822e47e55d6b5c76 commit: 00bf4d64ecb01027be40c32d822e47e55d6b5c76 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-07T08:59:14-07:00 summary: bpo-37513: Change ValueError to TypeError in an example in ctypes doc (GH-14615) (cherry picked from commit f6cdd3ff687ebbf8209d793a18a042ea495c4aeb) Co-authored-by: Hai Shi files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index df9ccbf39084..6a5299145f95 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -565,7 +565,7 @@ Here is a simple example of a POINT structure, which contains two integers named >>> POINT(1, 2, 3) Traceback (most recent call last): File "", line 1, in - ValueError: too many initializers + TypeError: too many initializers >>> You can, however, build much more complicated structures. A structure can From webhook-mailer at python.org Sun Jul 7 17:37:54 2019 From: webhook-mailer at python.org (Jason R. Coombs) Date: Sun, 07 Jul 2019 21:37:54 -0000 Subject: [Python-checkins] bpo-37520: Correct behavior for zipfile.Path.parent (GH-14638) Message-ID: https://github.com/python/cpython/commit/38f44b4a4adc37e8f5f8971917d8b3145f351a56 commit: 38f44b4a4adc37e8f5f8971917d8b3145f351a56 branch: master author: Jason R. Coombs committer: GitHub date: 2019-07-07T17:37:50-04:00 summary: bpo-37520: Correct behavior for zipfile.Path.parent (GH-14638) * bpo-37520: Correct behavior for zipfile.Path.parent * ?? Added by blurb_it. files: A Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 19b550f80187..0c8ffcdbf14a 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2514,5 +2514,16 @@ def test_parent(self): assert (root / 'a').parent.at == '' assert (root / 'a' / 'b').parent.at == 'a/' + def test_dir_parent(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + assert (root / 'b').parent.at == '' + assert (root / 'b/').parent.at == '' + + def test_missing_dir_parent(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + assert (root / 'missing dir/').parent.at == '' + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 62f2fd27d3ce..3c1f1235034a 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2236,7 +2236,7 @@ def _add_implied_dirs(names): @property def parent(self): - parent_at = posixpath.dirname(self.at) + parent_at = posixpath.dirname(self.at.rstrip('/')) if parent_at: parent_at += '/' return self._next(parent_at) diff --git a/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst b/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst new file mode 100644 index 000000000000..6584d3ebe1ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst @@ -0,0 +1 @@ +Correct behavior for zipfile.Path.parent when the path object identifies a subdirectory. \ No newline at end of file From webhook-mailer at python.org Sun Jul 7 18:05:57 2019 From: webhook-mailer at python.org (Jason R. Coombs) Date: Sun, 07 Jul 2019 22:05:57 -0000 Subject: [Python-checkins] bpo-37520: Correct behavior for zipfile.Path.parent (GH-14638) (GH-14641) Message-ID: https://github.com/python/cpython/commit/66905d14672517d50dc8ba516b9839f9ddbcc131 commit: 66905d14672517d50dc8ba516b9839f9ddbcc131 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Jason R. Coombs date: 2019-07-07T18:05:53-04:00 summary: bpo-37520: Correct behavior for zipfile.Path.parent (GH-14638) (GH-14641) * bpo-37520: Correct behavior for zipfile.Path.parent * ?? Added by blurb_it. (cherry picked from commit 38f44b4a4adc37e8f5f8971917d8b3145f351a56) Co-authored-by: Jason R. Coombs files: A Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 19b550f80187..0c8ffcdbf14a 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2514,5 +2514,16 @@ def test_parent(self): assert (root / 'a').parent.at == '' assert (root / 'a' / 'b').parent.at == 'a/' + def test_dir_parent(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + assert (root / 'b').parent.at == '' + assert (root / 'b/').parent.at == '' + + def test_missing_dir_parent(self): + for zipfile_abcde in self.zipfile_abcde(): + root = zipfile.Path(zipfile_abcde) + assert (root / 'missing dir/').parent.at == '' + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 62f2fd27d3ce..3c1f1235034a 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2236,7 +2236,7 @@ def _add_implied_dirs(names): @property def parent(self): - parent_at = posixpath.dirname(self.at) + parent_at = posixpath.dirname(self.at.rstrip('/')) if parent_at: parent_at += '/' return self._next(parent_at) diff --git a/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst b/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst new file mode 100644 index 000000000000..6584d3ebe1ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst @@ -0,0 +1 @@ +Correct behavior for zipfile.Path.parent when the path object identifies a subdirectory. \ No newline at end of file From webhook-mailer at python.org Mon Jul 8 04:19:33 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Mon, 08 Jul 2019 08:19:33 -0000 Subject: [Python-checkins] bpo-37337: Add _PyObject_CallMethodNoArgs() (GH-14267) Message-ID: https://github.com/python/cpython/commit/762f93ff2efd6b7ef0177cad57939c0ab2002eac commit: 762f93ff2efd6b7ef0177cad57939c0ab2002eac branch: master author: Jeroen Demeyer committer: Inada Naoki date: 2019-07-08T17:19:25+09:00 summary: bpo-37337: Add _PyObject_CallMethodNoArgs() (GH-14267) files: M Doc/c-api/object.rst M Include/cpython/abstract.h M Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst M Modules/_asynciomodule.c M Modules/_collectionsmodule.c M Modules/_ctypes/_ctypes.c M Modules/_cursesmodule.c M Modules/_datetimemodule.c M Modules/_dbmmodule.c M Modules/_gdbmmodule.c M Modules/_io/_iomodule.c M Modules/_io/bufferedio.c M Modules/_io/iobase.c M Modules/_io/stringio.c M Modules/_io/textio.c M Modules/_pickle.c M Modules/_posixsubprocess.c M Modules/_sqlite/connection.c M Modules/_sqlite/cursor.c M Modules/_sqlite/module.c M Modules/_threadmodule.c M Modules/faulthandler.c M Modules/mmapmodule.c M Modules/ossaudiodev.c M Modules/selectmodule.c M Objects/abstract.c M Objects/descrobject.c M Objects/fileobject.c M Objects/odictobject.c M Objects/typeobject.c M Objects/weakrefobject.c M Python/bltinmodule.c M Python/errors.c M Python/import.c M Python/pylifecycle.c M Python/pythonrun.c M Python/traceback.c diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 6d138558d60a..8ca034452954 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -364,6 +364,17 @@ Object Protocol *NULL* on failure. +.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name) + + Call a method of the Python object *obj* without arguments, + where the name of the method is given as a Python string object in *name*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + .. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) Call a callable Python object *callable*, using diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index c9a8a0754588..e9a23195f414 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -156,6 +156,13 @@ PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod( PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static inline PyObject * +_PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) +{ + return _PyObject_VectorcallMethod(name, &self, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + /* Like PyObject_CallMethod(), but expect a _Py_Identifier* as the method name. */ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, @@ -184,6 +191,13 @@ _PyObject_VectorcallMethodId( return _PyObject_VectorcallMethod(oname, args, nargsf, kwnames); } +static inline PyObject * +_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) +{ + return _PyObject_VectorcallMethodId(name, &self, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); /* Guess the size of object 'o' using len(o) or o.__length_hint__(). diff --git a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst b/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst index 96ba2d0ec085..df0e807e1166 100644 --- a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst +++ b/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst @@ -1 +1,2 @@ -Add :c:func:`_PyObject_VectorcallMethod` for fast calling of methods. +Add fast functions for calling methods: :c:func:`_PyObject_VectorcallMethod` +and :c:func:`_PyObject_CallMethodNoArgs` diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 443acc5723c3..6c469d2a2ec5 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -332,7 +332,7 @@ get_event_loop(void) return NULL; } - loop = _PyObject_CallMethodId(policy, &PyId_get_event_loop, NULL); + loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop); Py_DECREF(policy); return loop; } @@ -493,7 +493,7 @@ future_init(FutureObj *fut, PyObject *loop) } fut->fut_loop = loop; - res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL); + res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug); if (res == NULL) { return -1; } @@ -1295,9 +1295,8 @@ FutureObj_repr(FutureObj *fut) ENSURE_FUTURE_ALIVE(fut) - PyObject *rinfo = _PyObject_CallMethodIdObjArgs((PyObject*)fut, - &PyId__repr_info, - NULL); + PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut, + &PyId__repr_info); if (rinfo == NULL) { return NULL; } @@ -2197,8 +2196,7 @@ _asyncio_Task_cancel_impl(TaskObj *self) PyObject *res; int is_true; - res = _PyObject_CallMethodId( - self->task_fut_waiter, &PyId_cancel, NULL); + res = _PyObject_CallMethodIdNoArgs(self->task_fut_waiter, &PyId_cancel); if (res == NULL) { return NULL; } @@ -2735,7 +2733,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); + r = _PyObject_CallMethodIdNoArgs(result, &PyId_cancel); if (r == NULL) { return NULL; } @@ -2826,7 +2824,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodId(result, &PyId_cancel, NULL); + r = _PyObject_CallMethodIdNoArgs(result, &PyId_cancel); if (r == NULL) { return NULL; } diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 7e9cf8a283a2..1d23973fd056 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -2039,7 +2039,7 @@ defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored)) args = PyTuple_Pack(1, dd->default_factory); if (args == NULL) return NULL; - items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, NULL); + items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items); if (items == NULL) { Py_DECREF(args); return NULL; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index c6ae487b4cf0..c1941c16400e 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -3974,7 +3974,7 @@ _build_result(PyObject *result, PyObject *callargs, _Py_IDENTIFIER(__ctypes_from_outparam__); v = PyTuple_GET_ITEM(callargs, i); - v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL); + v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__); if (v == NULL || numretvals == 1) { Py_DECREF(callargs); return v; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 2435e1c12955..8595b6282c1b 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2906,7 +2906,7 @@ _curses_getwin(PyObject *module, PyObject *file) if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto error; - data = _PyObject_CallMethodId(file, &PyId_read, NULL); + data = _PyObject_CallMethodIdNoArgs(file, &PyId_read); if (data == NULL) goto error; if (!PyBytes_Check(data)) { diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 2e0211cbbef8..0546368d1df7 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1659,7 +1659,7 @@ time_time(void) if (time != NULL) { _Py_IDENTIFIER(time); - result = _PyObject_CallMethodId(time, &PyId_time, NULL); + result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); Py_DECREF(time); } return result; @@ -1918,7 +1918,7 @@ get_float_as_integer_ratio(PyObject *floatobj) PyObject *ratio; assert(floatobj && PyFloat_Check(floatobj)); - ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL); + ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); if (ratio == NULL) { return NULL; } @@ -3162,7 +3162,7 @@ date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) static PyObject * date_str(PyDateTime_Date *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); + return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); } @@ -3188,7 +3188,7 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) &format)) return NULL; - tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL); + tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); if (tuple == NULL) return NULL; result = wrap_strftime((PyObject *)self, format, tuple, @@ -4175,7 +4175,7 @@ time_repr(PyDateTime_Time *self) static PyObject * time_str(PyDateTime_Time *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL); + return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); } static PyObject * diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index ea0a9d6fc957..b317b57e7ae5 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -370,7 +370,7 @@ static PyObject * dbm__exit__(PyObject *self, PyObject *args) { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId(self, &PyId_close, NULL); + return _PyObject_CallMethodIdNoArgs(self, &PyId_close); } diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 77e788752506..dd4a348d136c 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -497,7 +497,7 @@ static PyObject * dbm__exit__(PyObject *self, PyObject *args) { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId(self, &PyId_close, NULL); + return _PyObject_CallMethodIdNoArgs(self, &PyId_close); } static PyMethodDef dbm_methods[] = { diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 5c2f019e840b..96426e0276ab 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -400,7 +400,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, /* buffering */ if (buffering < 0) { - PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL); + PyObject *res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); if (res == NULL) goto error; isatty = PyLong_AsLong(res); @@ -494,7 +494,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, if (result != NULL) { PyObject *exc, *val, *tb, *close_result; PyErr_Fetch(&exc, &val, &tb); - close_result = _PyObject_CallMethodId(result, &PyId_close, NULL); + close_result = _PyObject_CallMethodIdNoArgs(result, &PyId_close); _PyErr_ChainExceptions(exc, val, tb); Py_XDECREF(close_result); Py_DECREF(result); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 44e12db6a30e..9e7e5f3d0935 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -461,7 +461,7 @@ static PyObject * buffered_simple_flush(buffered *self, PyObject *args) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush); } static int @@ -513,7 +513,7 @@ buffered_close(buffered *self, PyObject *args) } /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (!ENTER_BUFFERED(self)) return NULL; if (res == NULL) @@ -521,7 +521,7 @@ buffered_close(buffered *self, PyObject *args) else Py_DECREF(res); - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL); + res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close); if (self->buffer) { PyMem_Free(self->buffer); @@ -545,7 +545,7 @@ buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) { PyObject *raw, *res; CHECK_INITIALIZED(self) - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); @@ -562,21 +562,21 @@ static PyObject * buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable); } static PyObject * buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable); } static PyObject * buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable); } static PyObject * @@ -599,14 +599,14 @@ static PyObject * buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno); } static PyObject * buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) { CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); + return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty); } /* Forward decls */ @@ -670,7 +670,7 @@ _buffered_raw_tell(buffered *self) { Py_off_t n; PyObject *res; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); + res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell); if (res == NULL) return -1; n = PyNumber_AsOff_t(res, PyExc_ValueError); @@ -1350,8 +1350,8 @@ buffered_iternext(buffered *self) line = _buffered_readline(self, -1); } else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); + line = _PyObject_CallMethodNoArgs((PyObject *)self, + _PyIO_str_readline); if (line && !PyBytes_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a bytes object, " @@ -1566,7 +1566,7 @@ _bufferedreader_read_all(buffered *self) } /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); + data = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read); if (data == NULL) goto cleanup; if (data != Py_None && !PyBytes_Check(data)) { diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 82cc77676523..d51fc944e1a6 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -235,7 +235,7 @@ _io__IOBase_close_impl(PyObject *self) Py_RETURN_NONE; } - res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs(self, _PyIO_str_flush); PyErr_Fetch(&exc, &val, &tb); rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True); @@ -281,8 +281,7 @@ iobase_finalize(PyObject *self) finalization process. */ if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True)) PyErr_Clear(); - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, - NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close); /* Silencing I/O errors is bad, but printing spurious tracebacks is equally as bad, and potentially more frequent (because of shutdown issues). */ @@ -383,7 +382,7 @@ _io__IOBase_seekable_impl(PyObject *self) PyObject * _PyIOBase_check_seekable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL); + PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_seekable); if (res == NULL) return NULL; if (res != Py_True) { @@ -416,7 +415,7 @@ _io__IOBase_readable_impl(PyObject *self) PyObject * _PyIOBase_check_readable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL); + PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_readable); if (res == NULL) return NULL; if (res != Py_True) { @@ -449,7 +448,7 @@ _io__IOBase_writable_impl(PyObject *self) PyObject * _PyIOBase_check_writable(PyObject *self, PyObject *args) { - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL); + PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_writable); if (res == NULL) return NULL; if (res != Py_True) { @@ -478,7 +477,7 @@ iobase_enter(PyObject *self, PyObject *args) static PyObject * iobase_exit(PyObject *self, PyObject *args) { - return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL); + return _PyObject_CallMethodNoArgs(self, _PyIO_str_close); } /* Lower-level APIs */ @@ -656,7 +655,7 @@ iobase_iter(PyObject *self) static PyObject * iobase_iternext(PyObject *self) { - PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL); + PyObject *line = _PyObject_CallMethodNoArgs(self, _PyIO_str_readline); if (line == NULL) return NULL; @@ -921,7 +920,7 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) if (n < 0) { _Py_IDENTIFIER(readall); - return _PyObject_CallMethodId(self, &PyId_readall, NULL); + return _PyObject_CallMethodIdNoArgs(self, &PyId_readall); } /* TODO: allocate a bytes object directly instead and manually construct diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 9e9724db2d33..810cad6d63ce 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -408,8 +408,8 @@ stringio_iternext(stringio *self) } else { /* XXX is subclassing StringIO really supported? */ - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); + line = _PyObject_CallMethodNoArgs((PyObject *)self, + _PyIO_str_readline); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a str object, " diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 021231e4c6b5..ed1dc005c69a 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -527,8 +527,8 @@ _io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) unsigned long long flag; if (self->decoder != Py_None) { - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); + PyObject *state = _PyObject_CallMethodNoArgs(self->decoder, + _PyIO_str_getstate); if (state == NULL) return NULL; if (!PyTuple_Check(state)) { @@ -601,7 +601,7 @@ _io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) self->seennl = 0; self->pendingcr = 0; if (self->decoder != Py_None) - return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); + return _PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); else Py_RETURN_NONE; } @@ -862,7 +862,7 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info, PyObject *res; int r; - res = _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL); + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); if (res == NULL) return -1; @@ -917,7 +917,7 @@ _textiowrapper_set_encoder(textio *self, PyObject *codec_info, PyObject *res; int r; - res = _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL); + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); if (res == NULL) return -1; @@ -963,8 +963,8 @@ _textiowrapper_fix_encoder_state(textio *self) self->encoding_start_of_stream = 1; - PyObject *cookieObj = PyObject_CallMethodObjArgs( - self->buffer, _PyIO_str_tell, NULL); + PyObject *cookieObj = _PyObject_CallMethodNoArgs( + self->buffer, _PyIO_str_tell); if (cookieObj == NULL) { return -1; } @@ -1126,7 +1126,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, state = IO_STATE(); if (state == NULL) goto error; - fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL); + fileno = _PyObject_CallMethodIdNoArgs(buffer, &PyId_fileno); /* Ignore only AttributeError and UnsupportedOperation */ if (fileno == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError) || @@ -1241,7 +1241,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, } } - res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL); + res = _PyObject_CallMethodIdNoArgs(buffer, &PyId_seekable); if (res == NULL) goto error; r = PyObject_IsTrue(res); @@ -1386,7 +1386,7 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, return NULL; } - PyObject *res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + PyObject *res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) { return NULL; } @@ -1525,7 +1525,7 @@ _io_TextIOWrapper_detach_impl(textio *self) { PyObject *buffer, *res; CHECK_ATTACHED(self); - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); @@ -1720,7 +1720,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) } if (needflush) { - ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL); + ret = _PyObject_CallMethodNoArgs(self->buffer, _PyIO_str_flush); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1730,7 +1730,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) Py_CLEAR(self->snapshot); if (self->decoder) { - ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); + ret = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1810,9 +1810,8 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /* To prepare for tell(), we need to snapshot a point in the file * where the decoder's input buffer is empty. */ - - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); + PyObject *state = _PyObject_CallMethodNoArgs(self->decoder, + _PyIO_str_getstate); if (state == NULL) return -1; /* Given this, we know there was a valid snapshot point @@ -1935,7 +1934,7 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) if (n < 0) { /* Read everything */ - PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL); + PyObject *bytes = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_read); PyObject *decoded; if (bytes == NULL) goto fail; @@ -2396,7 +2395,7 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) utf-16, that we are expecting a BOM). */ if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); + res = _PyObject_CallMethodNoArgs(self->decoder, _PyIO_str_reset); else res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "((yi))", "", cookie->dec_flags); @@ -2411,7 +2410,7 @@ _textiowrapper_encoder_reset(textio *self, int start_of_stream) { PyObject *res; if (start_of_stream) { - res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL); + res = _PyObject_CallMethodNoArgs(self->encoder, _PyIO_str_reset); self->encoding_start_of_stream = 1; } else { @@ -2476,7 +2475,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) * sync the underlying buffer with the current position. */ Py_DECREF(cookieObj); - cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL); + cookieObj = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_tell); if (cookieObj == NULL) goto fail; break; @@ -2492,7 +2491,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); if (res == NULL) goto fail; Py_DECREF(res); @@ -2500,7 +2499,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); if (self->decoder) { - res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); + res = _PyObject_CallMethodIdNoArgs(self->decoder, &PyId_reset); if (res == NULL) goto fail; Py_DECREF(res); @@ -2540,7 +2539,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; } - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) goto fail; Py_DECREF(res); @@ -2663,12 +2662,12 @@ _io_TextIOWrapper_tell_impl(textio *self) if (_textiowrapper_writeflush(self) < 0) return NULL; - res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); if (res == NULL) goto fail; Py_DECREF(res); - posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL); + posobj = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_tell); if (posobj == NULL) goto fail; @@ -2704,15 +2703,15 @@ _io_TextIOWrapper_tell_impl(textio *self) chars_to_skip = self->decoded_chars_used; /* Decoder state will be restored at the end */ - saved_state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); + saved_state = _PyObject_CallMethodNoArgs(self->decoder, + _PyIO_str_getstate); if (saved_state == NULL) goto fail; #define DECODER_GETSTATE() do { \ PyObject *dec_buffer; \ - PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \ - _PyIO_str_getstate, NULL); \ + PyObject *_state = _PyObject_CallMethodNoArgs(self->decoder, \ + _PyIO_str_getstate); \ if (_state == NULL) \ goto fail; \ if (!PyTuple_Check(_state)) { \ @@ -2874,7 +2873,7 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) CHECK_ATTACHED(self) - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); + res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush); if (res == NULL) return NULL; Py_DECREF(res); @@ -2963,7 +2962,7 @@ _io_TextIOWrapper_fileno_impl(textio *self) /*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_fileno); } /*[clinic input] @@ -2975,7 +2974,7 @@ _io_TextIOWrapper_seekable_impl(textio *self) /*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_seekable); } /*[clinic input] @@ -2987,7 +2986,7 @@ _io_TextIOWrapper_readable_impl(textio *self) /*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_readable); } /*[clinic input] @@ -2999,7 +2998,7 @@ _io_TextIOWrapper_writable_impl(textio *self) /*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_writable); } /*[clinic input] @@ -3011,7 +3010,7 @@ _io_TextIOWrapper_isatty_impl(textio *self) /*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ { CHECK_ATTACHED(self); - return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_isatty); } /*[clinic input] @@ -3027,7 +3026,7 @@ _io_TextIOWrapper_flush_impl(textio *self) self->telling = self->seekable; if (_textiowrapper_writeflush(self) < 0) return NULL; - return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL); + return _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_flush); } /*[clinic input] @@ -3064,13 +3063,13 @@ _io_TextIOWrapper_close_impl(textio *self) else PyErr_Clear(); } - res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); + res = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_flush); if (res == NULL) PyErr_Fetch(&exc, &val, &tb); else Py_DECREF(res); - res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL); + res = _PyObject_CallMethodIdNoArgs(self->buffer, &PyId_close); if (exc != NULL) { _PyErr_ChainExceptions(exc, val, tb); Py_CLEAR(res); @@ -3092,8 +3091,8 @@ textiowrapper_iternext(textio *self) line = _textiowrapper_readline(self, -1); } else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); + line = _PyObject_CallMethodNoArgs((PyObject *)self, + _PyIO_str_readline); if (line && !PyUnicode_Check(line)) { PyErr_Format(PyExc_OSError, "readline() should have returned a str object, " diff --git a/Modules/_pickle.c b/Modules/_pickle.c index d6d1250d04f7..0b0928f5cd2f 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -3305,7 +3305,7 @@ save_dict(PicklerObject *self, PyObject *obj) } else { _Py_IDENTIFIER(items); - items = _PyObject_CallMethodId(obj, &PyId_items, NULL); + items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); if (items == NULL) goto error; iter = PyObject_GetIter(items); diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 81a23c6d3300..60c8eab90a15 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -60,7 +60,7 @@ _enable_gc(int need_to_reenable_gc, PyObject *gc_module) if (need_to_reenable_gc) { PyErr_Fetch(&exctype, &val, &tb); - result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL); + result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_enable); if (exctype != NULL) { PyErr_Restore(exctype, val, tb); } @@ -606,7 +606,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) gc_module = PyImport_ImportModule("gc"); if (gc_module == NULL) return NULL; - result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, NULL); + result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_isenabled); if (result == NULL) { Py_DECREF(gc_module); return NULL; @@ -617,7 +617,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) Py_DECREF(gc_module); return NULL; } - result = _PyObject_CallMethodId(gc_module, &PyId_disable, NULL); + result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_disable); if (result == NULL) { Py_DECREF(gc_module); return NULL; diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 08604b99a6ac..30a9b889a9df 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -713,7 +713,7 @@ void _pysqlite_final_callback(sqlite3_context* context) PyErr_Fetch(&exception, &value, &tb); restore = 1; - function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, NULL); + function_result = _PyObject_CallMethodIdNoArgs(*aggregate_instance, &PyId_finalize); Py_DECREF(*aggregate_instance); @@ -1275,7 +1275,7 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } @@ -1304,7 +1304,7 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } @@ -1333,7 +1333,7 @@ PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* PyObject* result = 0; PyObject* method = 0; - cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, NULL); + cursor = _PyObject_CallMethodIdNoArgs((PyObject*)self, &PyId_cursor); if (!cursor) { goto error; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e6fcac887fe3..6d9685b29642 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -106,7 +106,7 @@ _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) if (!key) { return NULL; } - upcase_key = _PyObject_CallMethodId(key, &PyId_upper, NULL); + upcase_key = _PyObject_CallMethodIdNoArgs(key, &PyId_upper); Py_DECREF(key); if (!upcase_key) { return NULL; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 9fe0dc952f0b..d5c353ea7bee 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -203,7 +203,7 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) } /* convert the name to upper case */ - name = _PyObject_CallMethodId(orig_name, &PyId_upper, NULL); + name = _PyObject_CallMethodIdNoArgs(orig_name, &PyId_upper); if (!name) { goto error; } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 9ab8e7a0ceb3..6665827fe2ba 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1358,7 +1358,7 @@ thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, _PyErr_Display(file, exc_type, exc_value, exc_traceback); /* Call file.flush() */ - PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); if (!res) { return -1; } diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index f2b5a503f4ee..2331051f7907 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -172,7 +172,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return fd; } - result = _PyObject_CallMethodId(file, &PyId_fileno, NULL); + result = _PyObject_CallMethodIdNoArgs(file, &PyId_fileno); if (result == NULL) return -1; @@ -190,7 +190,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return -1; } - result = _PyObject_CallMethodId(file, &PyId_flush, NULL); + result = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); if (result != NULL) Py_DECREF(result); else { @@ -1305,7 +1305,7 @@ faulthandler_init_enable(void) return -1; } - PyObject *res = _PyObject_CallMethodId(module, &PyId_enable, NULL); + PyObject *res = _PyObject_CallMethodIdNoArgs(module, &PyId_enable); Py_DECREF(module); if (res == NULL) { return -1; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 9e3414f94e31..51ab3f054f24 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -692,7 +692,7 @@ mmap__exit__method(PyObject *self, PyObject *args) { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId(self, &PyId_close, NULL); + return _PyObject_CallMethodIdNoArgs(self, &PyId_close); } #ifdef MS_WINDOWS diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index affaf1d9680b..6e050e4bc4ca 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -539,7 +539,7 @@ oss_exit(PyObject *self, PyObject *unused) { _Py_IDENTIFIER(close); - PyObject *ret = _PyObject_CallMethodId(self, &PyId_close, NULL); + PyObject *ret = _PyObject_CallMethodIdNoArgs(self, &PyId_close); if (!ret) return NULL; Py_DECREF(ret); diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index ed71d8b0d598..2e06a897132a 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -1634,7 +1634,7 @@ select_epoll___exit___impl(pyEpoll_Object *self, PyObject *exc_type, { _Py_IDENTIFIER(close); - return _PyObject_CallMethodId((PyObject *)self, &PyId_close, NULL); + return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_close); } static PyGetSetDef pyepoll_getsetlist[] = { diff --git a/Objects/abstract.c b/Objects/abstract.c index 86178a74ea38..db1c3064db6f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2221,7 +2221,7 @@ method_output_as_list(PyObject *o, _Py_Identifier *meth_id) PyObject *it, *result, *meth_output; assert(o != NULL); - meth_output = _PyObject_CallMethodId(o, meth_id, NULL); + meth_output = _PyObject_CallMethodIdNoArgs(o, meth_id); if (meth_output == NULL || PyList_CheckExact(meth_output)) { return meth_output; } diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 99855d8ae44c..edce250c7948 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1019,28 +1019,28 @@ static PyObject * mappingproxy_keys(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(keys); - return _PyObject_CallMethodId(pp->mapping, &PyId_keys, NULL); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_keys); } static PyObject * mappingproxy_values(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(values); - return _PyObject_CallMethodId(pp->mapping, &PyId_values, NULL); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_values); } static PyObject * mappingproxy_items(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(items); - return _PyObject_CallMethodId(pp->mapping, &PyId_items, NULL); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_items); } static PyObject * mappingproxy_copy(mappingproxyobject *pp, PyObject *Py_UNUSED(ignored)) { _Py_IDENTIFIER(copy); - return _PyObject_CallMethodId(pp->mapping, &PyId_copy, NULL); + return _PyObject_CallMethodIdNoArgs(pp->mapping, &PyId_copy); } /* WARNING: mappingproxy methods must not give access diff --git a/Objects/fileobject.c b/Objects/fileobject.c index a21e490817eb..0faf7e70b5d8 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -61,7 +61,7 @@ PyFile_GetLine(PyObject *f, int n) } if (n <= 0) { - result = _PyObject_CallMethodIdObjArgs(f, &PyId_readline, NULL); + result = _PyObject_CallMethodIdNoArgs(f, &PyId_readline); } else { result = _PyObject_CallMethodId(f, &PyId_readline, "i", n); diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 4c9ae3bc9346..dfbd30a976ca 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -920,7 +920,7 @@ odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored)) if (args == NULL) goto Done; - items = _PyObject_CallMethodIdObjArgs((PyObject *)od, &PyId_items, NULL); + items = _PyObject_CallMethodIdNoArgs((PyObject *)od, &PyId_items); if (items == NULL) goto Done; @@ -1421,8 +1421,8 @@ odict_repr(PyODictObject *self) Py_SIZE(pieces) = count; } else { - PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, - &PyId_items, NULL); + PyObject *items = _PyObject_CallMethodIdNoArgs((PyObject *)self, + &PyId_items); if (items == NULL) goto Done; pieces = PySequence_List(items); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3b9a537936a3..96021eeccc57 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4425,7 +4425,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, PyObject *items; _Py_IDENTIFIER(items); - items = _PyObject_CallMethodIdObjArgs(obj, &PyId_items, NULL); + items = _PyObject_CallMethodIdNoArgs(obj, &PyId_items); if (items == NULL) { Py_CLEAR(*listitems); return -1; diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index ae3f6dca9eed..e8a429ab5b54 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -455,7 +455,7 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ - return _PyObject_CallMethodId(proxy, &PyId_##special, NULL); \ + return _PyObject_CallMethodIdNoArgs(proxy, &PyId_##special); \ } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5de43636d96b..65110d8d12c6 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1889,7 +1889,7 @@ builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject if (do_flush == -1) return NULL; else if (do_flush) { - tmp = _PyObject_CallMethodId(file, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); if (tmp == NULL) return NULL; else @@ -1959,7 +1959,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) } /* First of all, flush stderr */ - tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); if (tmp == NULL) PyErr_Clear(); else @@ -1968,7 +1968,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) /* We should only use (GNU) readline if Python's sys.stdin and sys.stdout are the same as C's stdin and stdout, because we need to pass it those. */ - tmp = _PyObject_CallMethodId(fin, &PyId_fileno, NULL); + tmp = _PyObject_CallMethodIdNoArgs(fin, &PyId_fileno); if (tmp == NULL) { PyErr_Clear(); tty = 0; @@ -1981,7 +1981,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) tty = fd == fileno(stdin) && isatty(fd); } if (tty) { - tmp = _PyObject_CallMethodId(fout, &PyId_fileno, NULL); + tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_fileno); if (tmp == NULL) { PyErr_Clear(); tty = 0; @@ -2019,7 +2019,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) stdin_errors_str = PyUnicode_AsUTF8(stdin_errors); if (!stdin_encoding_str || !stdin_errors_str) goto _readline_errors; - tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); if (tmp == NULL) PyErr_Clear(); else @@ -2114,7 +2114,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt) if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) return NULL; } - tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); if (tmp == NULL) PyErr_Clear(); else diff --git a/Python/errors.c b/Python/errors.c index a7d40c132d7b..b935341636f7 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1263,7 +1263,7 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, } /* Explicitly call file.flush() */ - PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); if (!res) { return -1; } diff --git a/Python/import.c b/Python/import.c index 76866ae645a7..df258751c82e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -539,7 +539,7 @@ _PyImport_Cleanup(PyThreadState *tstate) } else { _Py_IDENTIFIER(clear); - if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL) { + if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) { PyErr_WriteUnraisable(NULL); } } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 10765dab8f5d..e3333db4328a 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1106,7 +1106,7 @@ flush_std_files(void) int status = 0; if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush); if (tmp == NULL) { PyErr_WriteUnraisable(fout); status = -1; @@ -1116,7 +1116,7 @@ flush_std_files(void) } if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + tmp = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); if (tmp == NULL) { PyErr_Clear(); status = -1; @@ -1762,7 +1762,7 @@ create_stdio(const PyConfig *config, PyObject* io, text = PyUnicode_FromString(name); if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) goto error; - res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL); + res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty); if (res == NULL) goto error; isatty = PyObject_IsTrue(res); @@ -2026,7 +2026,7 @@ _Py_FatalError_PrintExc(int fd) Py_XDECREF(tb); /* sys.stderr may be buffered: call sys.stderr.flush() */ - res = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); + res = _PyObject_CallMethodIdNoArgs(ferr, &PyId_flush); if (res == NULL) { _PyErr_Clear(tstate); } @@ -2220,7 +2220,7 @@ wait_for_thread_shutdown(PyThreadState *tstate) /* else: threading not imported */ return; } - result = _PyObject_CallMethodId(threading, &PyId__shutdown, NULL); + result = _PyObject_CallMethodIdNoArgs(threading, &PyId__shutdown); if (result == NULL) { PyErr_WriteUnraisable(threading); } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f1d946a0b0f8..608908607873 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -978,7 +978,7 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t Py_XDECREF(seen); /* Call file.flush() */ - PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush); if (!res) { /* Silently ignore file.flush() error */ PyErr_Clear(); @@ -1072,7 +1072,7 @@ flush_io(void) f = _PySys_GetObjectId(&PyId_stderr); if (f != NULL) { - r = _PyObject_CallMethodId(f, &PyId_flush, NULL); + r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); if (r) Py_DECREF(r); else @@ -1080,7 +1080,7 @@ flush_io(void) } f = _PySys_GetObjectId(&PyId_stdout); if (f != NULL) { - r = _PyObject_CallMethodId(f, &PyId_flush, NULL); + r = _PyObject_CallMethodIdNoArgs(f, &PyId_flush); if (r) Py_DECREF(r); else diff --git a/Python/traceback.c b/Python/traceback.c index 0463eb6d8c98..f396f1ad983c 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -430,7 +430,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) if (fob == NULL) { PyErr_Clear(); - res = _PyObject_CallMethodId(binary, &PyId_close, NULL); + res = _PyObject_CallMethodIdNoArgs(binary, &PyId_close); Py_DECREF(binary); if (res) Py_DECREF(res); @@ -450,7 +450,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) break; } } - res = _PyObject_CallMethodId(fob, &PyId_close, NULL); + res = _PyObject_CallMethodIdNoArgs(fob, &PyId_close); if (res) Py_DECREF(res); else From webhook-mailer at python.org Mon Jul 8 04:49:19 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jul 2019 08:49:19 -0000 Subject: [Python-checkins] bpo-37421: test_concurrent_futures stops ForkServer (GH-14643) Message-ID: https://github.com/python/cpython/commit/e676244235895aeb6ec3b81ca3ccf4a70e487919 commit: e676244235895aeb6ec3b81ca3ccf4a70e487919 branch: master author: Victor Stinner committer: GitHub date: 2019-07-08T10:49:11+02:00 summary: bpo-37421: test_concurrent_futures stops ForkServer (GH-14643) test_concurrent_futures now explicitly stops the ForkServer instance if it's running. files: A Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst M Lib/test/test_concurrent_futures.py diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index c782d4c6e881..ff9a49380340 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -1309,6 +1309,9 @@ def tearDownModule(): # cleanup multiprocessing multiprocessing.process._cleanup() + # Stop the ForkServer process if it's running + from multiprocessing import forkserver + forkserver._forkserver._stop() # bpo-37421: Explicitly call _run_finalizers() to remove immediately # temporary directories created by multiprocessing.util.get_temp_dir(). multiprocessing.util._run_finalizers() diff --git a/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst b/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst new file mode 100644 index 000000000000..0766d70f6eda --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst @@ -0,0 +1,2 @@ +test_concurrent_futures now explicitly stops the ForkServer instance if it's +running. From webhook-mailer at python.org Mon Jul 8 05:52:04 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jul 2019 09:52:04 -0000 Subject: [Python-checkins] bpo-37421: test_concurrent_futures stops ForkServer (GH-14643) (GH-14645) Message-ID: https://github.com/python/cpython/commit/cdada40b23b1f7f527797ba7cb14c25820b05981 commit: cdada40b23b1f7f527797ba7cb14c25820b05981 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Victor Stinner date: 2019-07-08T11:51:49+02:00 summary: bpo-37421: test_concurrent_futures stops ForkServer (GH-14643) (GH-14645) test_concurrent_futures now explicitly stops the ForkServer instance if it's running. (cherry picked from commit e676244235895aeb6ec3b81ca3ccf4a70e487919) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst M Lib/test/test_concurrent_futures.py diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index fa298207f6c5..98c9bc9b507a 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -1310,6 +1310,9 @@ def tearDownModule(): # cleanup multiprocessing multiprocessing.process._cleanup() + # Stop the ForkServer process if it's running + from multiprocessing import forkserver + forkserver._forkserver._stop() # bpo-37421: Explicitly call _run_finalizers() to remove immediately # temporary directories created by multiprocessing.util.get_temp_dir(). multiprocessing.util._run_finalizers() diff --git a/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst b/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst new file mode 100644 index 000000000000..0766d70f6eda --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst @@ -0,0 +1,2 @@ +test_concurrent_futures now explicitly stops the ForkServer instance if it's +running. From webhook-mailer at python.org Mon Jul 8 12:57:48 2019 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 08 Jul 2019 16:57:48 -0000 Subject: [Python-checkins] bpo-37149: Replace dead link for online Tkinter reference (GH-14616) Message-ID: https://github.com/python/cpython/commit/317c33e67cb6076c5a87a66c75e8c35ac581398d commit: 317c33e67cb6076c5a87a66c75e8c35ac581398d branch: 3.6 author: Ned Deily committer: Ned Deily date: 2019-07-08T12:50:54-04:00 summary: bpo-37149: Replace dead link for online Tkinter reference (GH-14616) Also fix a name misspelling. Co-authored-by: Terry Jan Reedy files: M Doc/library/tkinter.rst diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 60cf892e0888..2515cf4f8b08 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -31,7 +31,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. `TKDocs `_ Extensive tutorial plus friendlier widget pages for some of the widgets. - `Tkinter reference: a GUI for Python `_ + `Tkinter 8.5 reference: a GUI for Python `_ On-line reference material. `Tkinter docs from effbot `_ @@ -41,7 +41,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. Book by Mark Lutz, has excellent coverage of Tkinter. `Modern Tkinter for Busy Python Developers `_ - Book by Mark Rozerman about building attractive and modern graphical user interfaces with Python and Tkinter. + Book by Mark Roseman about building attractive and modern graphical user interfaces with Python and Tkinter. `Python and Tkinter Programming `_ Book by John Grayson (ISBN 1-884777-81-3). From webhook-mailer at python.org Mon Jul 8 17:06:45 2019 From: webhook-mailer at python.org (Julien Palard) Date: Mon, 08 Jul 2019 21:06:45 -0000 Subject: [Python-checkins] Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Message-ID: https://github.com/python/cpython/commit/2da622ff77a763327895656779370b80a833d95c commit: 2da622ff77a763327895656779370b80a833d95c branch: master author: Julien Palard committer: GitHub date: 2019-07-08T23:06:32+02:00 summary: Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Initial report by Michael Blankenship on docs@ files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 79111f8518d9..92c042e26dfb 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -920,7 +920,7 @@ extracted for you: bracketing constructs: ``a = f(1, 2) + g(3, 4)``. * Name your classes and functions consistently; the convention is to use - ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions + ``UpperCamelCase`` for classes and ``lowercase_with_underscores`` for functions and methods. Always use ``self`` as the name for the first method argument (see :ref:`tut-firstclasses` for more on classes and methods). From webhook-mailer at python.org Mon Jul 8 17:08:11 2019 From: webhook-mailer at python.org (Julien Palard) Date: Mon, 08 Jul 2019 21:08:11 -0000 Subject: [Python-checkins] Doc: Fix example title. (GH-14639) Message-ID: https://github.com/python/cpython/commit/66b4150f6f001640521ae6c9571cd4325cd67394 commit: 66b4150f6f001640521ae6c9571cd4325cd67394 branch: master author: Julien Palard committer: GitHub date: 2019-07-08T23:08:07+02:00 summary: Doc: Fix example title. (GH-14639) files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 8575f8a72af3..9dd557fabaae 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3815,7 +3815,7 @@ copying. >>> z.nbytes 48 - Cast 1D/unsigned char to 2D/unsigned long:: + Cast 1D/unsigned long to 2D/unsigned long:: >>> buf = struct.pack("L"*6, *list(range(6))) >>> x = memoryview(buf) From webhook-mailer at python.org Mon Jul 8 17:14:02 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jul 2019 21:14:02 -0000 Subject: [Python-checkins] Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Message-ID: https://github.com/python/cpython/commit/975d4d3651c5fe9422801d8f7145486b23d46a13 commit: 975d4d3651c5fe9422801d8f7145486b23d46a13 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-08T14:13:57-07:00 summary: Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Initial report by Michael Blankenship on docs@ (cherry picked from commit 2da622ff77a763327895656779370b80a833d95c) Co-authored-by: Julien Palard files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 79111f8518d9..92c042e26dfb 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -920,7 +920,7 @@ extracted for you: bracketing constructs: ``a = f(1, 2) + g(3, 4)``. * Name your classes and functions consistently; the convention is to use - ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions + ``UpperCamelCase`` for classes and ``lowercase_with_underscores`` for functions and methods. Always use ``self`` as the name for the first method argument (see :ref:`tut-firstclasses` for more on classes and methods). From webhook-mailer at python.org Mon Jul 8 17:14:03 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jul 2019 21:14:03 -0000 Subject: [Python-checkins] Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Message-ID: https://github.com/python/cpython/commit/6f5574866c4017e438b7ac5f5374889389c4eb24 commit: 6f5574866c4017e438b7ac5f5374889389c4eb24 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-08T14:13:59-07:00 summary: Doc: Fix: Proper UpperCamelCase and lowercase. (GH-14644) Initial report by Michael Blankenship on docs@ (cherry picked from commit 2da622ff77a763327895656779370b80a833d95c) Co-authored-by: Julien Palard files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index c3ce1205e52e..482a34399c7b 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -744,7 +744,7 @@ extracted for you: bracketing constructs: ``a = f(1, 2) + g(3, 4)``. * Name your classes and functions consistently; the convention is to use - ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions + ``UpperCamelCase`` for classes and ``lowercase_with_underscores`` for functions and methods. Always use ``self`` as the name for the first method argument (see :ref:`tut-firstclasses` for more on classes and methods). From webhook-mailer at python.org Mon Jul 8 17:17:35 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jul 2019 21:17:35 -0000 Subject: [Python-checkins] Doc: Fix example title. (GH-14639) Message-ID: https://github.com/python/cpython/commit/54348f46f8c8c023b7e78f9cebe8e54818227b92 commit: 54348f46f8c8c023b7e78f9cebe8e54818227b92 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-08T14:17:32-07:00 summary: Doc: Fix example title. (GH-14639) (cherry picked from commit 66b4150f6f001640521ae6c9571cd4325cd67394) Co-authored-by: Julien Palard files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 35a17a180809..965167640c98 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3801,7 +3801,7 @@ copying. >>> z.nbytes 48 - Cast 1D/unsigned char to 2D/unsigned long:: + Cast 1D/unsigned long to 2D/unsigned long:: >>> buf = struct.pack("L"*6, *list(range(6))) >>> x = memoryview(buf) From webhook-mailer at python.org Mon Jul 8 17:18:00 2019 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Mon, 08 Jul 2019 21:18:00 -0000 Subject: [Python-checkins] bpo-18374: fix wrong col_offset of some ast.BinOp instances (GH-14607) Message-ID: https://github.com/python/cpython/commit/110a47c4f42cf4db88edc1876899fff8f05190fb commit: 110a47c4f42cf4db88edc1876899fff8f05190fb branch: master author: Carl Friedrich Bolz-Tereick committer: Ivan Levkivskyi date: 2019-07-08T22:17:56+01:00 summary: bpo-18374: fix wrong col_offset of some ast.BinOp instances (GH-14607) Nested BinOp instances (e.g. a+b+c) had a wrong col_offset for the second BinOp (e.g. 2 instead of 0 in the example). Fix it by using the correct st node to copy the line and col_offset from in ast.c. files: A Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst M Lib/test/test_ast.py M Misc/ACKS M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e251e254afdd..1e07c573c846 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -576,6 +576,36 @@ def bad_normalize(*args): with support.swap_attr(unicodedata, 'normalize', bad_normalize): self.assertRaises(TypeError, ast.parse, '\u03D5') + def test_issue18374_binop_col_offset(self): + tree = ast.parse('4+5+6+7') + parent_binop = tree.body[0].value + child_binop = parent_binop.left + grandchild_binop = child_binop.left + self.assertEqual(parent_binop.col_offset, 0) + self.assertEqual(parent_binop.end_col_offset, 7) + self.assertEqual(child_binop.col_offset, 0) + self.assertEqual(child_binop.end_col_offset, 5) + self.assertEqual(grandchild_binop.col_offset, 0) + self.assertEqual(grandchild_binop.end_col_offset, 3) + + tree = ast.parse('4+5-\\\n 6-7') + parent_binop = tree.body[0].value + child_binop = parent_binop.left + grandchild_binop = child_binop.left + self.assertEqual(parent_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(parent_binop.end_col_offset, 4) + self.assertEqual(parent_binop.end_lineno, 2) + + self.assertEqual(child_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(child_binop.end_col_offset, 2) + self.assertEqual(parent_binop.end_lineno, 2) + + self.assertEqual(grandchild_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(grandchild_binop.end_col_offset, 3) + self.assertEqual(parent_binop.end_lineno, 2) class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/ACKS b/Misc/ACKS index 36fe727c8421..d916c45a8e44 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -178,6 +178,7 @@ Nikolay Bogoychev David Bolen Wouter Bolsterlee Gawain Bolton +Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond M?d?ric Boquien diff --git a/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst new file mode 100644 index 000000000000..f9e99e0474a4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst @@ -0,0 +1,2 @@ +Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances +which had a too large value in some situations. diff --git a/Python/ast.c b/Python/ast.c index 16895ce62ec0..8dc86c23d62d 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2645,7 +2645,7 @@ ast_for_binop(struct compiling *c, const node *n) return NULL; tmp_result = BinOp(result, newoperator, tmp, - LINENO(next_oper), next_oper->n_col_offset, + LINENO(n), n->n_col_offset, CHILD(n, i * 2 + 2)->n_end_lineno, CHILD(n, i * 2 + 2)->n_end_col_offset, c->c_arena); From webhook-mailer at python.org Mon Jul 8 17:18:19 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jul 2019 21:18:19 -0000 Subject: [Python-checkins] Doc: Fix example title. (GH-14639) Message-ID: https://github.com/python/cpython/commit/8b1135fc602859119ce2e649b070c0d8d9dce7ca commit: 8b1135fc602859119ce2e649b070c0d8d9dce7ca branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-08T14:18:15-07:00 summary: Doc: Fix example title. (GH-14639) (cherry picked from commit 66b4150f6f001640521ae6c9571cd4325cd67394) Co-authored-by: Julien Palard files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 3b74331e51f2..d35c171aba39 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3733,7 +3733,7 @@ copying. >>> z.nbytes 48 - Cast 1D/unsigned char to 2D/unsigned long:: + Cast 1D/unsigned long to 2D/unsigned long:: >>> buf = struct.pack("L"*6, *list(range(6))) >>> x = memoryview(buf) From webhook-mailer at python.org Mon Jul 8 17:41:38 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jul 2019 21:41:38 -0000 Subject: [Python-checkins] bpo-18374: fix wrong col_offset of some ast.BinOp instances (GH-14607) Message-ID: https://github.com/python/cpython/commit/c7be35c2abd598f02a633879133caec356593241 commit: c7be35c2abd598f02a633879133caec356593241 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-08T14:41:34-07:00 summary: bpo-18374: fix wrong col_offset of some ast.BinOp instances (GH-14607) Nested BinOp instances (e.g. a+b+c) had a wrong col_offset for the second BinOp (e.g. 2 instead of 0 in the example). Fix it by using the correct st node to copy the line and col_offset from in ast.c. (cherry picked from commit 110a47c4f42cf4db88edc1876899fff8f05190fb) Co-authored-by: Carl Friedrich Bolz-Tereick files: A Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst M Lib/test/test_ast.py M Misc/ACKS M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e251e254afdd..1e07c573c846 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -576,6 +576,36 @@ def bad_normalize(*args): with support.swap_attr(unicodedata, 'normalize', bad_normalize): self.assertRaises(TypeError, ast.parse, '\u03D5') + def test_issue18374_binop_col_offset(self): + tree = ast.parse('4+5+6+7') + parent_binop = tree.body[0].value + child_binop = parent_binop.left + grandchild_binop = child_binop.left + self.assertEqual(parent_binop.col_offset, 0) + self.assertEqual(parent_binop.end_col_offset, 7) + self.assertEqual(child_binop.col_offset, 0) + self.assertEqual(child_binop.end_col_offset, 5) + self.assertEqual(grandchild_binop.col_offset, 0) + self.assertEqual(grandchild_binop.end_col_offset, 3) + + tree = ast.parse('4+5-\\\n 6-7') + parent_binop = tree.body[0].value + child_binop = parent_binop.left + grandchild_binop = child_binop.left + self.assertEqual(parent_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(parent_binop.end_col_offset, 4) + self.assertEqual(parent_binop.end_lineno, 2) + + self.assertEqual(child_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(child_binop.end_col_offset, 2) + self.assertEqual(parent_binop.end_lineno, 2) + + self.assertEqual(grandchild_binop.col_offset, 0) + self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(grandchild_binop.end_col_offset, 3) + self.assertEqual(parent_binop.end_lineno, 2) class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/ACKS b/Misc/ACKS index 082fa567f23a..f427d8b5a929 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -178,6 +178,7 @@ Nikolay Bogoychev David Bolen Wouter Bolsterlee Gawain Bolton +Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond M?d?ric Boquien diff --git a/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst new file mode 100644 index 000000000000..f9e99e0474a4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst @@ -0,0 +1,2 @@ +Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances +which had a too large value in some situations. diff --git a/Python/ast.c b/Python/ast.c index 2a5941572148..317a42b7f121 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2645,7 +2645,7 @@ ast_for_binop(struct compiling *c, const node *n) return NULL; tmp_result = BinOp(result, newoperator, tmp, - LINENO(next_oper), next_oper->n_col_offset, + LINENO(n), n->n_col_offset, CHILD(n, i * 2 + 2)->n_end_lineno, CHILD(n, i * 2 + 2)->n_end_col_offset, c->c_arena); From webhook-mailer at python.org Mon Jul 8 17:54:52 2019 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 08 Jul 2019 21:54:52 -0000 Subject: [Python-checkins] [3.7] bpo-37500: Revert commit 85ed1712e428f93408f56fc684816f9a85b0ebc0 (GH-14605) Message-ID: https://github.com/python/cpython/commit/4834c80d799471a6c9ddaad9c5c82c8af156e4fd commit: 4834c80d799471a6c9ddaad9c5c82c8af156e4fd branch: 3.7 author: Pablo Galindo committer: Ned Deily date: 2019-07-08T12:08:31-04:00 summary: [3.7] bpo-37500: Revert commit 85ed1712e428f93408f56fc684816f9a85b0ebc0 (GH-14605) https://bugs.python.org/issue37500 files: M Lib/test/test_syntax.py M Python/compile.c M Python/peephole.c diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 4918e5c4c428..2b96a94401a8 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -650,20 +650,6 @@ def error2(): def test_break_outside_loop(self): self._check_error("break", "outside loop") - def test_yield_outside_function(self): - self._check_error("if 0: yield", "outside function") - self._check_error("class C:\n if 0: yield", "outside function") - - def test_return_outside_function(self): - self._check_error("if 0: return", "outside function") - self._check_error("class C:\n if 0: return", "outside function") - - def test_break_outside_loop(self): - self._check_error("if 0: break", "outside loop") - - def test_continue_outside_loop(self): - self._check_error("if 0: continue", "not properly in loop") - def test_unexpected_indent(self): self._check_error("foo()\n bar()\n", "unexpected indent", subclass=IndentationError) diff --git a/Python/compile.c b/Python/compile.c index d2729d4c6ca3..5688ef8479c0 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2301,12 +2301,13 @@ compiler_if(struct compiler *c, stmt_ty s) return 0; constant = expr_constant(s->v.If.test); - /* constant = 0: "if 0" Leave the optimizations to - * the pephole optimizer to check for syntax errors - * in the block. + /* constant = 0: "if 0" * constant = 1: "if 1", "if 2", ... * constant = -1: rest */ - if (constant == 1) { + if (constant == 0) { + if (s->v.If.orelse) + VISIT_SEQ(c, stmt, s->v.If.orelse); + } else if (constant == 1) { VISIT_SEQ(c, stmt, s->v.If.body); } else { if (asdl_seq_LEN(s->v.If.orelse)) { diff --git a/Python/peephole.c b/Python/peephole.c index 277a216ae075..95b3dbb6bf51 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -304,18 +304,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case LOAD_CONST: cumlc = lastlc + 1; if (nextop != POP_JUMP_IF_FALSE || - !ISBASICBLOCK(blocks, op_start, i + 1)) { + !ISBASICBLOCK(blocks, op_start, i + 1) || + !PyObject_IsTrue(PyList_GET_ITEM(consts, get_arg(codestr, i)))) break; - } - PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); - int is_true = PyObject_IsTrue(cnt); - if (is_true == -1) { - goto exitError; - } - if (is_true == 1) { - fill_nops(codestr, op_start, nexti + 1); - cumlc = 0; - } + fill_nops(codestr, op_start, nexti + 1); + cumlc = 0; break; /* Try to fold tuples of constants. From webhook-mailer at python.org Tue Jul 9 06:37:00 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 10:37:00 -0000 Subject: [Python-checkins] bpo-37322: Fix test_ssl.test_pha_required_nocert() ResourceWarning (GH-14662) Message-ID: https://github.com/python/cpython/commit/cf9c41c422de3774862db964fe3153086bad3f61 commit: cf9c41c422de3774862db964fe3153086bad3f61 branch: master author: Victor Stinner committer: GitHub date: 2019-07-09T12:36:55+02:00 summary: bpo-37322: Fix test_ssl.test_pha_required_nocert() ResourceWarning (GH-14662) Close the TLS connection in test_pha_required_nocert() of test_ssl to fix a ResourceWarning. files: M Lib/test/test_ssl.py diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d2b9e2046d0e..166e28683e26 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2382,6 +2382,7 @@ def run(self): if self.server.chatty and support.verbose: sys.stdout.write(err.args[1]) # test_pha_required_nocert is expecting this exception + self.close() raise ssl.SSLError('tlsv13 alert certificate required') except OSError: if self.server.chatty: From webhook-mailer at python.org Tue Jul 9 07:00:27 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 11:00:27 -0000 Subject: [Python-checkins] bpo-37526: Add support.catch_threading_exception() (GH-14664) Message-ID: https://github.com/python/cpython/commit/91b4f7ab7f9a5e0908b91379ee085ae087a76483 commit: 91b4f7ab7f9a5e0908b91379ee085ae087a76483 branch: master author: Victor Stinner committer: GitHub date: 2019-07-09T13:00:23+02:00 summary: bpo-37526: Add support.catch_threading_exception() (GH-14664) Context manager catching threading.Thread exception using threading.excepthook. files: A Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst M Doc/library/test.rst M Lib/test/support/__init__.py diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 920c018084b8..7d62a94d839b 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1081,6 +1081,39 @@ The :mod:`test.support` module defines the following functions: :exc:`PermissionError` is raised. +.. function:: catch_threading_exception() + + Context manager catching :class:`threading.Thread` exception using + :func:`threading.excepthook`. + + Attributes set when an exception is catched: + + * ``exc_type`` + * ``exc_value`` + * ``exc_traceback`` + * ``thread`` + + See :func:`threading.excepthook` documentation. + + These attributes are deleted at the context manager exit. + + Usage:: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + + .. versionadded:: 3.8 + + .. function:: catch_unraisable_exception() Context manager catching unraisable exception using diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 611c1cc9776d..423bb3ebd80d 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3159,3 +3159,60 @@ def __enter__(self): def __exit__(self, *exc_info): sys.unraisablehook = self._old_hook del self.unraisable + + +class catch_threading_exception: + """ + Context manager catching threading.Thread exception using + threading.excepthook. + + Attributes set when an exception is catched: + + * exc_type + * exc_value + * exc_traceback + * thread + + See threading.excepthook() documentation for these attributes. + + These attributes are deleted at the context manager exit. + + Usage: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + """ + + def __init__(self): + self.exc_type = None + self.exc_value = None + self.exc_traceback = None + self.thread = None + self._old_hook = None + + def _hook(self, args): + self.exc_type = args.exc_type + self.exc_value = args.exc_value + self.exc_traceback = args.exc_traceback + self.thread = args.thread + + def __enter__(self): + self._old_hook = threading.excepthook + threading.excepthook = self._hook + return self + + def __exit__(self, *exc_info): + threading.excepthook = self._old_hook + del self.exc_type + del self.exc_value + del self.exc_traceback + del self.thread diff --git a/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst new file mode 100644 index 000000000000..aff6b6d1f12c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst @@ -0,0 +1,2 @@ +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. From webhook-mailer at python.org Tue Jul 9 07:30:56 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 09 Jul 2019 11:30:56 -0000 Subject: [Python-checkins] bpo-37120: Fix _ssl get_num_tickets() (GH-14668) Message-ID: https://github.com/python/cpython/commit/76611c7c0af6b2f4d0d98a5db827d34cff54ce25 commit: 76611c7c0af6b2f4d0d98a5db827d34cff54ce25 branch: master author: Victor Stinner committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-09T04:30:52-07:00 summary: bpo-37120: Fix _ssl get_num_tickets() (GH-14668) Replace PyLong_FromLong() with PyLong_FromSize_t(): SSL_CTX_get_num_tickets() return type is size_t. https://bugs.python.org/issue37120 files: M Modules/_ssl.c diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 3351af6cdefd..da30cbb758e2 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3641,7 +3641,7 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_num_tickets(PySSLContext *self, void *c) { - return PyLong_FromLong(SSL_CTX_get_num_tickets(self->ctx)); + return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); } static int From webhook-mailer at python.org Tue Jul 9 07:35:51 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 11:35:51 -0000 Subject: [Python-checkins] Revert "bpo-37322: Fix test_ssl.test_pha_required_nocert() ResourceWarning (GH-14662)" (GH-14669) Message-ID: https://github.com/python/cpython/commit/61b1bc56069719fc6f17c73fdf2193636dbf6cc2 commit: 61b1bc56069719fc6f17c73fdf2193636dbf6cc2 branch: master author: Victor Stinner committer: GitHub date: 2019-07-09T13:35:47+02:00 summary: Revert "bpo-37322: Fix test_ssl.test_pha_required_nocert() ResourceWarning (GH-14662)" (GH-14669) This reverts commit cf9c41c422de3774862db964fe3153086bad3f61. files: M Lib/test/test_ssl.py diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 166e28683e26..d2b9e2046d0e 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2382,7 +2382,6 @@ def run(self): if self.server.chatty and support.verbose: sys.stdout.write(err.args[1]) # test_pha_required_nocert is expecting this exception - self.close() raise ssl.SSLError('tlsv13 alert certificate required') except OSError: if self.server.chatty: From webhook-mailer at python.org Tue Jul 9 07:36:03 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 11:36:03 -0000 Subject: [Python-checkins] bpo-37526: Add support.catch_threading_exception() (GH-14664) (GH-14666) Message-ID: https://github.com/python/cpython/commit/58f2c7f424fe91ba035918f0f66306af73a37543 commit: 58f2c7f424fe91ba035918f0f66306af73a37543 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Victor Stinner date: 2019-07-09T13:35:59+02:00 summary: bpo-37526: Add support.catch_threading_exception() (GH-14664) (GH-14666) Context manager catching threading.Thread exception using threading.excepthook. (cherry picked from commit 91b4f7ab7f9a5e0908b91379ee085ae087a76483) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst M Doc/library/test.rst M Lib/test/support/__init__.py diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 920c018084b8..7d62a94d839b 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1081,6 +1081,39 @@ The :mod:`test.support` module defines the following functions: :exc:`PermissionError` is raised. +.. function:: catch_threading_exception() + + Context manager catching :class:`threading.Thread` exception using + :func:`threading.excepthook`. + + Attributes set when an exception is catched: + + * ``exc_type`` + * ``exc_value`` + * ``exc_traceback`` + * ``thread`` + + See :func:`threading.excepthook` documentation. + + These attributes are deleted at the context manager exit. + + Usage:: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + + .. versionadded:: 3.8 + + .. function:: catch_unraisable_exception() Context manager catching unraisable exception using diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 1c91fc434eec..a0fe086049a1 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3157,3 +3157,60 @@ def __enter__(self): def __exit__(self, *exc_info): sys.unraisablehook = self._old_hook del self.unraisable + + +class catch_threading_exception: + """ + Context manager catching threading.Thread exception using + threading.excepthook. + + Attributes set when an exception is catched: + + * exc_type + * exc_value + * exc_traceback + * thread + + See threading.excepthook() documentation for these attributes. + + These attributes are deleted at the context manager exit. + + Usage: + + with support.catch_threading_exception() as cm: + # code spawning a thread which raises an exception + ... + + # check the thread exception, use cm attributes: + # exc_type, exc_value, exc_traceback, thread + ... + + # exc_type, exc_value, exc_traceback, thread attributes of cm no longer + # exists at this point + # (to avoid reference cycles) + """ + + def __init__(self): + self.exc_type = None + self.exc_value = None + self.exc_traceback = None + self.thread = None + self._old_hook = None + + def _hook(self, args): + self.exc_type = args.exc_type + self.exc_value = args.exc_value + self.exc_traceback = args.exc_traceback + self.thread = args.thread + + def __enter__(self): + self._old_hook = threading.excepthook + threading.excepthook = self._hook + return self + + def __exit__(self, *exc_info): + threading.excepthook = self._old_hook + del self.exc_type + del self.exc_value + del self.exc_traceback + del self.thread diff --git a/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst new file mode 100644 index 000000000000..aff6b6d1f12c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst @@ -0,0 +1,2 @@ +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. From webhook-mailer at python.org Tue Jul 9 08:20:11 2019 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Tue, 09 Jul 2019 12:20:11 -0000 Subject: [Python-checkins] bpo-18374: fix tests to check the correct thing about line numbers (GH-14659) Message-ID: https://github.com/python/cpython/commit/430a9f44fe22f029ae8cfeecb46621d7e199414b commit: 430a9f44fe22f029ae8cfeecb46621d7e199414b branch: master author: Carl Friedrich Bolz-Tereick committer: Ivan Levkivskyi date: 2019-07-09T13:20:01+01:00 summary: bpo-18374: fix tests to check the correct thing about line numbers (GH-14659) files: M Lib/test/test_ast.py diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 1e07c573c846..6bd27ce12a62 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -598,14 +598,14 @@ def test_issue18374_binop_col_offset(self): self.assertEqual(parent_binop.end_lineno, 2) self.assertEqual(child_binop.col_offset, 0) - self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(child_binop.lineno, 1) self.assertEqual(child_binop.end_col_offset, 2) - self.assertEqual(parent_binop.end_lineno, 2) + self.assertEqual(child_binop.end_lineno, 2) self.assertEqual(grandchild_binop.col_offset, 0) - self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(grandchild_binop.lineno, 1) self.assertEqual(grandchild_binop.end_col_offset, 3) - self.assertEqual(parent_binop.end_lineno, 2) + self.assertEqual(grandchild_binop.end_lineno, 1) class ASTHelpers_Test(unittest.TestCase): maxDiff = None From webhook-mailer at python.org Tue Jul 9 08:33:58 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 12:33:58 -0000 Subject: [Python-checkins] bpo-37322: ssl test_pha_required_nocert() ignores expected SSLError (GH-14670) Message-ID: https://github.com/python/cpython/commit/73ea54620a6f91c3f2e53880373dd47813691a21 commit: 73ea54620a6f91c3f2e53880373dd47813691a21 branch: master author: Victor Stinner committer: GitHub date: 2019-07-09T14:33:49+02:00 summary: bpo-37322: ssl test_pha_required_nocert() ignores expected SSLError (GH-14670) test_ssl.test_pha_required_nocert() now uses support.catch_threading_exception() to ignore the expected SSLError in ConnectionHandler of ThreadedEchoServer (it is only raised sometimes on Windows). files: M Lib/test/test_ssl.py diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d2b9e2046d0e..afc5be9a7e99 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4326,21 +4326,24 @@ def test_pha_required_nocert(self): server_context.verify_mode = ssl.CERT_REQUIRED client_context.post_handshake_auth = True - 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'PHA') - # receive CertificateRequest - self.assertEqual(s.recv(1024), b'OK\n') - # send empty Certificate + Finish - s.write(b'HASCERT') - # receive alert - with self.assertRaisesRegex( - ssl.SSLError, - 'tlsv13 alert certificate required'): - s.recv(1024) + # Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer + # (it is only raised sometimes on Windows) + with support.catch_threading_exception() as cm: + 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'PHA') + # receive CertificateRequest + self.assertEqual(s.recv(1024), b'OK\n') + # send empty Certificate + Finish + s.write(b'HASCERT') + # receive alert + with self.assertRaisesRegex( + ssl.SSLError, + 'tlsv13 alert certificate required'): + s.recv(1024) def test_pha_optional(self): if support.verbose: From webhook-mailer at python.org Tue Jul 9 08:43:04 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 09 Jul 2019 12:43:04 -0000 Subject: [Python-checkins] bpo-37120: Fix _ssl get_num_tickets() (GH-14668) Message-ID: https://github.com/python/cpython/commit/bbad695e7890513be7a9bc662e2d8ae13bfcd313 commit: bbad695e7890513be7a9bc662e2d8ae13bfcd313 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-09T05:42:49-07:00 summary: bpo-37120: Fix _ssl get_num_tickets() (GH-14668) Replace PyLong_FromLong() with PyLong_FromSize_t(): SSL_CTX_get_num_tickets() return type is size_t. https://bugs.python.org/issue37120 (cherry picked from commit 76611c7c0af6b2f4d0d98a5db827d34cff54ce25) Co-authored-by: Victor Stinner files: M Modules/_ssl.c diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 3351af6cdefd..da30cbb758e2 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3641,7 +3641,7 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) static PyObject * get_num_tickets(PySSLContext *self, void *c) { - return PyLong_FromLong(SSL_CTX_get_num_tickets(self->ctx)); + return PyLong_FromSize_t(SSL_CTX_get_num_tickets(self->ctx)); } static int From webhook-mailer at python.org Tue Jul 9 08:55:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 09 Jul 2019 12:55:14 -0000 Subject: [Python-checkins] bpo-37322: ssl test_pha_required_nocert() ignores expected SSLError (GH-14670) Message-ID: https://github.com/python/cpython/commit/4c403b8ca2d0ef44b691cceaeeac9e110fd3f05a commit: 4c403b8ca2d0ef44b691cceaeeac9e110fd3f05a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-09T05:55:08-07:00 summary: bpo-37322: ssl test_pha_required_nocert() ignores expected SSLError (GH-14670) test_ssl.test_pha_required_nocert() now uses support.catch_threading_exception() to ignore the expected SSLError in ConnectionHandler of ThreadedEchoServer (it is only raised sometimes on Windows). (cherry picked from commit 73ea54620a6f91c3f2e53880373dd47813691a21) Co-authored-by: Victor Stinner files: M Lib/test/test_ssl.py diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index f1b7aa731e9a..879d944f327e 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4320,21 +4320,24 @@ def test_pha_required_nocert(self): server_context.verify_mode = ssl.CERT_REQUIRED client_context.post_handshake_auth = True - 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'PHA') - # receive CertificateRequest - self.assertEqual(s.recv(1024), b'OK\n') - # send empty Certificate + Finish - s.write(b'HASCERT') - # receive alert - with self.assertRaisesRegex( - ssl.SSLError, - 'tlsv13 alert certificate required'): - s.recv(1024) + # Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer + # (it is only raised sometimes on Windows) + with support.catch_threading_exception() as cm: + 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'PHA') + # receive CertificateRequest + self.assertEqual(s.recv(1024), b'OK\n') + # send empty Certificate + Finish + s.write(b'HASCERT') + # receive alert + with self.assertRaisesRegex( + ssl.SSLError, + 'tlsv13 alert certificate required'): + s.recv(1024) def test_pha_optional(self): if support.verbose: From webhook-mailer at python.org Tue Jul 9 09:29:01 2019 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Tue, 09 Jul 2019 13:29:01 -0000 Subject: [Python-checkins] bpo-18374: fix tests to check the correct thing about line numbers (GH-14659) (GH-14672) Message-ID: https://github.com/python/cpython/commit/68bd9c5691c4899d21cc7fe6cce7cd22b2f5ccb0 commit: 68bd9c5691c4899d21cc7fe6cce7cd22b2f5ccb0 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ivan Levkivskyi date: 2019-07-09T14:28:56+01:00 summary: bpo-18374: fix tests to check the correct thing about line numbers (GH-14659) (GH-14672) (cherry picked from commit 430a9f44fe22f029ae8cfeecb46621d7e199414b) Co-authored-by: Carl Friedrich Bolz-Tereick files: M Lib/test/test_ast.py diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 1e07c573c846..6bd27ce12a62 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -598,14 +598,14 @@ def test_issue18374_binop_col_offset(self): self.assertEqual(parent_binop.end_lineno, 2) self.assertEqual(child_binop.col_offset, 0) - self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(child_binop.lineno, 1) self.assertEqual(child_binop.end_col_offset, 2) - self.assertEqual(parent_binop.end_lineno, 2) + self.assertEqual(child_binop.end_lineno, 2) self.assertEqual(grandchild_binop.col_offset, 0) - self.assertEqual(parent_binop.lineno, 1) + self.assertEqual(grandchild_binop.lineno, 1) self.assertEqual(grandchild_binop.end_col_offset, 3) - self.assertEqual(parent_binop.end_lineno, 2) + self.assertEqual(grandchild_binop.end_lineno, 1) class ASTHelpers_Test(unittest.TestCase): maxDiff = None From webhook-mailer at python.org Tue Jul 9 14:00:33 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jul 2019 18:00:33 -0000 Subject: [Python-checkins] bpo-27679: Remove set_bitfields() from _ctypes_test (GH-14648) Message-ID: https://github.com/python/cpython/commit/3a3db970de344efbb4017fb9dde9204f0fd4bbdc commit: 3a3db970de344efbb4017fb9dde9204f0fd4bbdc branch: master author: Hai Shi committer: Victor Stinner date: 2019-07-09T20:00:27+02:00 summary: bpo-27679: Remove set_bitfields() from _ctypes_test (GH-14648) files: M Modules/_ctypes/_ctypes_test.c diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index bae4976a08d3..4789d6bdda8c 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -425,30 +425,6 @@ struct BITS { #endif }; -EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) -{ - switch (name) { - case 'A': bits->A = value; break; - case 'B': bits->B = value; break; - case 'C': bits->C = value; break; - case 'D': bits->D = value; break; - case 'E': bits->E = value; break; - case 'F': bits->F = value; break; - case 'G': bits->G = value; break; - case 'H': bits->H = value; break; - case 'I': bits->I = value; break; -#ifdef SIGNED_SHORT_BITFIELDS - case 'M': bits->M = value; break; - case 'N': bits->N = value; break; - case 'O': bits->O = value; break; - case 'P': bits->P = value; break; - case 'Q': bits->Q = value; break; - case 'R': bits->R = value; break; - case 'S': bits->S = value; break; -#endif - } -} - EXPORT(int) unpack_bitfields(struct BITS *bits, char name) { switch (name) { From webhook-mailer at python.org Tue Jul 9 14:37:31 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 09 Jul 2019 18:37:31 -0000 Subject: [Python-checkins] bpo-26806: IDLE should run without docstrings (#14657) Message-ID: https://github.com/python/cpython/commit/6aeb2fe606408aae14c246470794f1303b3be812 commit: 6aeb2fe606408aae14c246470794f1303b3be812 branch: master author: Terry Jan Reedy committer: GitHub date: 2019-07-09T14:37:25-04:00 summary: bpo-26806: IDLE should run without docstrings (#14657) After fcf1d00, IDLE startup failed with python compiled without docstrings. files: M Lib/idlelib/idle_test/test_run.py M Lib/idlelib/run.py diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index d0f1e9207bb1..cad0b4d98f8e 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -292,6 +292,14 @@ def test_default_recursion_limit_preserved(self): new_reclimit = sys.getrecursionlimit() self.assertEqual(new_reclimit, orig_reclimit) + def test_fixdoc(self): + def func(): "docstring" + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "docstring\n\nmore") + func.__doc__ = None + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "more") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index c6ed76b23a2d..41e0ded44029 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -307,7 +307,12 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +def fixdoc(fun, text): + tem = (fun.__doc__ + '\n\n') if fun.__doc__ is not None else '' + fun.__doc__ = tem + textwrap.fill(textwrap.dedent(text)) + RECURSIONLIMIT_DELTA = 30 + def install_recursionlimit_wrappers(): """Install wrappers to always add 30 to the recursion limit.""" # see: bpo-26806 @@ -329,19 +334,17 @@ def setrecursionlimit(*args, **kwargs): return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) - setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible - uninterruptible loops. - """).strip()) + fixdoc(setrecursionlimit, f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops.""") @functools.wraps(sys.getrecursionlimit) def getrecursionlimit(): return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA - getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for - the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. - """).strip()) + fixdoc(getrecursionlimit, f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate + for the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit.""") # add the delta to the default recursion limit, to compensate sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) From webhook-mailer at python.org Tue Jul 9 14:59:30 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 09 Jul 2019 18:59:30 -0000 Subject: [Python-checkins] bpo-26806: IDLE should run without docstrings (GH-14657) (GH-14677) Message-ID: https://github.com/python/cpython/commit/b82188d9bad1774624cb1788dbdec2f0d7d65688 commit: b82188d9bad1774624cb1788dbdec2f0d7d65688 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-09T14:59:19-04:00 summary: bpo-26806: IDLE should run without docstrings (GH-14657) (GH-14677) After fcf1d00, IDLE startup failed with python compiled without docstrings. (cherry picked from commit 6aeb2fe606408aae14c246470794f1303b3be812) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/idle_test/test_run.py M Lib/idlelib/run.py diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index d0f1e9207bb1..cad0b4d98f8e 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -292,6 +292,14 @@ def test_default_recursion_limit_preserved(self): new_reclimit = sys.getrecursionlimit() self.assertEqual(new_reclimit, orig_reclimit) + def test_fixdoc(self): + def func(): "docstring" + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "docstring\n\nmore") + func.__doc__ = None + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "more") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index c6ed76b23a2d..41e0ded44029 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -307,7 +307,12 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +def fixdoc(fun, text): + tem = (fun.__doc__ + '\n\n') if fun.__doc__ is not None else '' + fun.__doc__ = tem + textwrap.fill(textwrap.dedent(text)) + RECURSIONLIMIT_DELTA = 30 + def install_recursionlimit_wrappers(): """Install wrappers to always add 30 to the recursion limit.""" # see: bpo-26806 @@ -329,19 +334,17 @@ def setrecursionlimit(*args, **kwargs): return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) - setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible - uninterruptible loops. - """).strip()) + fixdoc(setrecursionlimit, f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops.""") @functools.wraps(sys.getrecursionlimit) def getrecursionlimit(): return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA - getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for - the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. - """).strip()) + fixdoc(getrecursionlimit, f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate + for the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit.""") # add the delta to the default recursion limit, to compensate sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) From webhook-mailer at python.org Tue Jul 9 15:16:49 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 09 Jul 2019 19:16:49 -0000 Subject: [Python-checkins] bpo-26806: IDLE should run without docstrings (GH-14657) (GH-14678) Message-ID: https://github.com/python/cpython/commit/f54f062f68ac82fc3e7c92345b4d5fbe2534dc84 commit: f54f062f68ac82fc3e7c92345b4d5fbe2534dc84 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Terry Jan Reedy date: 2019-07-09T15:16:44-04:00 summary: bpo-26806: IDLE should run without docstrings (GH-14657) (GH-14678) After fcf1d00, IDLE startup failed with python compiled without docstrings. (cherry picked from commit 6aeb2fe606408aae14c246470794f1303b3be812) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/idle_test/test_run.py M Lib/idlelib/run.py diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index d0f1e9207bb1..cad0b4d98f8e 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -292,6 +292,14 @@ def test_default_recursion_limit_preserved(self): new_reclimit = sys.getrecursionlimit() self.assertEqual(new_reclimit, orig_reclimit) + def test_fixdoc(self): + def func(): "docstring" + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "docstring\n\nmore") + func.__doc__ = None + run.fixdoc(func, "more") + self.assertEqual(func.__doc__, "more") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index c6ed76b23a2d..41e0ded44029 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -307,7 +307,12 @@ def fix_scaling(root): font['size'] = round(-0.75*size) +def fixdoc(fun, text): + tem = (fun.__doc__ + '\n\n') if fun.__doc__ is not None else '' + fun.__doc__ = tem + textwrap.fill(textwrap.dedent(text)) + RECURSIONLIMIT_DELTA = 30 + def install_recursionlimit_wrappers(): """Install wrappers to always add 30 to the recursion limit.""" # see: bpo-26806 @@ -329,19 +334,17 @@ def setrecursionlimit(*args, **kwargs): return setrecursionlimit.__wrapped__(limit + RECURSIONLIMIT_DELTA) - setrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible - uninterruptible loops. - """).strip()) + fixdoc(setrecursionlimit, f"""\ + This IDLE wrapper adds {RECURSIONLIMIT_DELTA} to prevent possible + uninterruptible loops.""") @functools.wraps(sys.getrecursionlimit) def getrecursionlimit(): return getrecursionlimit.__wrapped__() - RECURSIONLIMIT_DELTA - getrecursionlimit.__doc__ += "\n\n" + textwrap.fill(textwrap.dedent(f"""\ - This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate for - the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit. - """).strip()) + fixdoc(getrecursionlimit, f"""\ + This IDLE wrapper subtracts {RECURSIONLIMIT_DELTA} to compensate + for the {RECURSIONLIMIT_DELTA} IDLE adds when setting the limit.""") # add the delta to the default recursion limit, to compensate sys.setrecursionlimit(sys.getrecursionlimit() + RECURSIONLIMIT_DELTA) From webhook-mailer at python.org Wed Jul 10 11:56:19 2019 From: webhook-mailer at python.org (Stefan Krah) Date: Wed, 10 Jul 2019 15:56:19 -0000 Subject: [Python-checkins] Really remove vcstdint.h. (#14686) Message-ID: https://github.com/python/cpython/commit/4749dbe54cfbcae64a06da2623e44f4017032207 commit: 4749dbe54cfbcae64a06da2623e44f4017032207 branch: master author: Stefan Krah committer: GitHub date: 2019-07-10T17:55:48+02:00 summary: Really remove vcstdint.h. (#14686) files: D Modules/_decimal/libmpdec/vcstdint.h M Modules/_decimal/libmpdec/README.txt M Modules/_decimal/libmpdec/vccompat.h diff --git a/Modules/_decimal/libmpdec/README.txt b/Modules/_decimal/libmpdec/README.txt index 96b72232d2ad..4e0e4f30bed0 100644 --- a/Modules/_decimal/libmpdec/README.txt +++ b/Modules/_decimal/libmpdec/README.txt @@ -30,7 +30,6 @@ Files required for the Python _decimal module Visual Studio only: ~~~~~~~~~~~~~~~~~~~ vccompat.h -> snprintf <==> sprintf_s and similar things. - vcstdint.h -> stdint.h (included in VS 2010 but not in VS 2008). vcdiv64.asm -> Double word division used in typearith.h. VS 2008 does not allow inline asm for x64. Also, it does not provide an intrinsic for double word division. diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/vccompat.h index dd131d8da264..2ba805dcc564 100644 --- a/Modules/_decimal/libmpdec/vccompat.h +++ b/Modules/_decimal/libmpdec/vccompat.h @@ -30,7 +30,7 @@ #define VCCOMPAT_H -/* Visual C fixes: no stdint.h, no snprintf ... */ +/* Visual C fixes: no snprintf ... */ #ifdef _MSC_VER #undef inline #define inline __inline diff --git a/Modules/_decimal/libmpdec/vcstdint.h b/Modules/_decimal/libmpdec/vcstdint.h deleted file mode 100644 index 17dcad4541ee..000000000000 --- a/Modules/_decimal/libmpdec/vcstdint.h +++ /dev/null @@ -1,232 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#if (_MSC_VER < 1300) && defined(__cplusplus) - extern "C++" { -#endif -# include -#if (_MSC_VER < 1300) && defined(__cplusplus) - } -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] From webhook-mailer at python.org Wed Jul 10 12:27:45 2019 From: webhook-mailer at python.org (Stefan Krah) Date: Wed, 10 Jul 2019 16:27:45 -0000 Subject: [Python-checkins] Rename memory.c to mpalloc.c for consistency with the header file. (#14687) Message-ID: https://github.com/python/cpython/commit/f117d871c467e82d98b127fd77d2542600d67c39 commit: f117d871c467e82d98b127fd77d2542600d67c39 branch: master author: Stefan Krah committer: GitHub date: 2019-07-10T18:27:38+02:00 summary: Rename memory.c to mpalloc.c for consistency with the header file. (#14687) files: A Modules/_decimal/libmpdec/mpalloc.c D Modules/_decimal/libmpdec/memory.c M Modules/_decimal/libmpdec/README.txt M PCbuild/_decimal.vcxproj M PCbuild/_decimal.vcxproj.filters M setup.py diff --git a/Modules/_decimal/libmpdec/README.txt b/Modules/_decimal/libmpdec/README.txt index 4e0e4f30bed0..dc97820a6eb0 100644 --- a/Modules/_decimal/libmpdec/README.txt +++ b/Modules/_decimal/libmpdec/README.txt @@ -20,7 +20,7 @@ Files required for the Python _decimal module context.c -> Context functions. io.{c,h} -> Conversions between mpd_t and ASCII strings, mpd_t formatting (allows UTF-8 fill character). - memory.{c,h} -> Allocation handlers with overflow detection + mpalloc.{c,h} -> Allocation handlers with overflow detection and functions for switching between static and dynamic mpd_t. mpdecimal.{c,h} -> All (quiet) functions of the specification. diff --git a/Modules/_decimal/libmpdec/memory.c b/Modules/_decimal/libmpdec/mpalloc.c similarity index 100% rename from Modules/_decimal/libmpdec/memory.c rename to Modules/_decimal/libmpdec/mpalloc.c diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index 465a7ade9a01..f0f387f3bfaa 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -131,7 +131,7 @@ - + diff --git a/PCbuild/_decimal.vcxproj.filters b/PCbuild/_decimal.vcxproj.filters index 7e19aa2f6596..1aa9d020d672 100644 --- a/PCbuild/_decimal.vcxproj.filters +++ b/PCbuild/_decimal.vcxproj.filters @@ -92,7 +92,7 @@ Source Files - + Source Files diff --git a/setup.py b/setup.py index e54d31f53338..3ec89cedfd57 100644 --- a/setup.py +++ b/setup.py @@ -2095,7 +2095,7 @@ def detect_decimal(self): '_decimal/libmpdec/fnt.c', '_decimal/libmpdec/fourstep.c', '_decimal/libmpdec/io.c', - '_decimal/libmpdec/memory.c', + '_decimal/libmpdec/mpalloc.c', '_decimal/libmpdec/mpdecimal.c', '_decimal/libmpdec/numbertheory.c', '_decimal/libmpdec/sixstep.c', From webhook-mailer at python.org Wed Jul 10 15:04:39 2019 From: webhook-mailer at python.org (Neil Schemenauer) Date: Wed, 10 Jul 2019 19:04:39 -0000 Subject: [Python-checkins] bpo-37537: Compute allocated blocks in _Py_GetAllocatedBlocks() (#14680) Message-ID: https://github.com/python/cpython/commit/5d25f2b70351fc6a56ce5513ccf5f58556c18837 commit: 5d25f2b70351fc6a56ce5513ccf5f58556c18837 branch: master author: Neil Schemenauer committer: GitHub date: 2019-07-10T12:04:16-07:00 summary: bpo-37537: Compute allocated blocks in _Py_GetAllocatedBlocks() (#14680) Keeping an account of allocated blocks slows down _PyObject_Malloc() and _PyObject_Free() by a measureable amount. Have _Py_GetAllocatedBlocks() iterate over the arenas to sum up the allocated blocks for pymalloc. files: A Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd.rst M Objects/obmalloc.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd.rst new file mode 100644 index 000000000000..abf874475d6d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd.rst @@ -0,0 +1,3 @@ +Compute allocated pymalloc blocks inside _Py_GetAllocatedBlocks(). This +slows down _Py_GetAllocatedBlocks() but gives a small speedup to +_PyObject_Malloc() and _PyObject_Free(). diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 622da3ad08fc..bb154c76ab18 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1206,12 +1206,29 @@ static size_t ntimes_arena_allocated = 0; /* High water mark (max value ever seen) for narenas_currently_allocated. */ static size_t narenas_highwater = 0; -static Py_ssize_t _Py_AllocatedBlocks = 0; +static Py_ssize_t raw_allocated_blocks; Py_ssize_t _Py_GetAllocatedBlocks(void) { - return _Py_AllocatedBlocks; + Py_ssize_t n = raw_allocated_blocks; + /* add up allocated blocks for used pools */ + for (uint i = 0; i < maxarenas; ++i) { + /* Skip arenas which are not allocated. */ + if (arenas[i].address == NULL) { + continue; + } + + uintptr_t base = (uintptr_t)_Py_ALIGN_UP(arenas[i].address, POOL_SIZE); + + /* visit every pool in the arena */ + assert(base <= (uintptr_t) arenas[i].pool_address); + for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + poolp p = (poolp)base; + n += p->ref.count; + } + } + return n; } @@ -1622,13 +1639,12 @@ _PyObject_Malloc(void *ctx, size_t nbytes) { void* ptr; if (pymalloc_alloc(ctx, &ptr, nbytes)) { - _Py_AllocatedBlocks++; return ptr; } ptr = PyMem_RawMalloc(nbytes); if (ptr != NULL) { - _Py_AllocatedBlocks++; + raw_allocated_blocks++; } return ptr; } @@ -1644,13 +1660,12 @@ _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) if (pymalloc_alloc(ctx, &ptr, nbytes)) { memset(ptr, 0, nbytes); - _Py_AllocatedBlocks++; return ptr; } ptr = PyMem_RawCalloc(nelem, elsize); if (ptr != NULL) { - _Py_AllocatedBlocks++; + raw_allocated_blocks++; } return ptr; } @@ -1899,10 +1914,10 @@ _PyObject_Free(void *ctx, void *p) return; } - _Py_AllocatedBlocks--; if (!pymalloc_free(ctx, p)) { /* pymalloc didn't allocate this address */ PyMem_RawFree(p); + raw_allocated_blocks--; } } From webhook-mailer at python.org Wed Jul 10 17:24:05 2019 From: webhook-mailer at python.org (Tim Peters) Date: Wed, 10 Jul 2019 21:24:05 -0000 Subject: [Python-checkins] Fix compiler warning in new code. (#14690) Message-ID: https://github.com/python/cpython/commit/b64c2c66e5cfe6d138b342ee58ee3b13a8d7ef16 commit: b64c2c66e5cfe6d138b342ee58ee3b13a8d7ef16 branch: master author: Tim Peters committer: GitHub date: 2019-07-10T16:24:01-05:00 summary: Fix compiler warning in new code. (#14690) uintptr_t is an integer type, and can't be compared to NULL directly. files: M Objects/obmalloc.c diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index bb154c76ab18..2c00efc255dc 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1215,7 +1215,7 @@ _Py_GetAllocatedBlocks(void) /* add up allocated blocks for used pools */ for (uint i = 0; i < maxarenas; ++i) { /* Skip arenas which are not allocated. */ - if (arenas[i].address == NULL) { + if (arenas[i].address == 0) { continue; } From webhook-mailer at python.org Wed Jul 10 22:43:08 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Thu, 11 Jul 2019 02:43:08 -0000 Subject: [Python-checkins] Document default parameter of .seek() in the signature. (GH-14691) Message-ID: https://github.com/python/cpython/commit/2a3d4d9c53dd4831c3ecf56bc7c4a289c33030d6 commit: 2a3d4d9c53dd4831c3ecf56bc7c4a289c33030d6 branch: master author: Benjamin Peterson committer: GitHub date: 2019-07-10T19:43:04-07:00 summary: Document default parameter of .seek() in the signature. (GH-14691) files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index fce9a747fd32..70e01153d419 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -327,7 +327,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -831,7 +831,7 @@ Text I/O If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is From webhook-mailer at python.org Wed Jul 10 22:49:41 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 02:49:41 -0000 Subject: [Python-checkins] Document default parameter of .seek() in the signature. (GH-14691) Message-ID: https://github.com/python/cpython/commit/2847a75c21821dce21ad496980031751330b33b9 commit: 2847a75c21821dce21ad496980031751330b33b9 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-10T19:49:37-07:00 summary: Document default parameter of .seek() in the signature. (GH-14691) (cherry picked from commit 2a3d4d9c53dd4831c3ecf56bc7c4a289c33030d6) Co-authored-by: Benjamin Peterson files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 966fb9cc7663..6bf56bc415b2 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -306,7 +306,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -810,7 +810,7 @@ Text I/O If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is From webhook-mailer at python.org Wed Jul 10 22:49:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 02:49:52 -0000 Subject: [Python-checkins] Document default parameter of .seek() in the signature. (GH-14691) Message-ID: https://github.com/python/cpython/commit/aca82977632fafa1d97c938999d76fae37c64f23 commit: aca82977632fafa1d97c938999d76fae37c64f23 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-10T19:49:49-07:00 summary: Document default parameter of .seek() in the signature. (GH-14691) (cherry picked from commit 2a3d4d9c53dd4831c3ecf56bc7c4a289c33030d6) Co-authored-by: Benjamin Peterson files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index fce9a747fd32..70e01153d419 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -327,7 +327,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -831,7 +831,7 @@ Text I/O If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is From webhook-mailer at python.org Wed Jul 10 22:50:03 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 02:50:03 -0000 Subject: [Python-checkins] Document default parameter of .seek() in the signature. (GH-14691) Message-ID: https://github.com/python/cpython/commit/0517375c4494b728171b0e306959e3f2703e0046 commit: 0517375c4494b728171b0e306959e3f2703e0046 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-10T19:49:59-07:00 summary: Document default parameter of .seek() in the signature. (GH-14691) (cherry picked from commit 2a3d4d9c53dd4831c3ecf56bc7c4a289c33030d6) Co-authored-by: Benjamin Peterson files: M Doc/library/io.rst diff --git a/Doc/library/io.rst b/Doc/library/io.rst index dcdd01cd0aa5..7c053f973aa1 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -304,7 +304,7 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given byte *offset*. *offset* is interpreted relative to the position indicated by *whence*. The default @@ -736,7 +736,7 @@ Text I/O If *limit* is specified, at most *limit* characters will be read. - .. method:: seek(offset[, whence]) + .. method:: seek(offset, whence=SEEK_SET) Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is From webhook-mailer at python.org Thu Jul 11 04:59:23 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Thu, 11 Jul 2019 08:59:23 -0000 Subject: [Python-checkins] bpo-37547: add _PyObject_CallMethodOneArg (GH-14685) Message-ID: https://github.com/python/cpython/commit/59ad110d7a7784d53d0b502eebce0346597a6bef commit: 59ad110d7a7784d53d0b502eebce0346597a6bef branch: master author: Jeroen Demeyer committer: Inada Naoki date: 2019-07-11T17:59:05+09:00 summary: bpo-37547: add _PyObject_CallMethodOneArg (GH-14685) files: M Doc/c-api/object.rst M Include/cpython/abstract.h M Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst M Modules/_abc.c M Modules/_asynciomodule.c M Modules/_ctypes/callproc.c M Modules/_datetimemodule.c M Modules/_elementtree.c M Modules/_io/bufferedio.c M Modules/_io/fileio.c M Modules/_io/textio.c M Modules/_io/winconsoleio.c M Modules/_pickle.c M Modules/_sqlite/connection.c M Modules/arraymodule.c M Modules/cjkcodecs/multibytecodec.c M Objects/dictobject.c M Objects/typeobject.c M Python/_warnings.c M Python/ceval.c M Python/import.c M Python/marshal.c M Python/sysmodule.c diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 8ca034452954..2cf032821afb 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -375,6 +375,18 @@ Object Protocol .. versionadded:: 3.9 +.. c:function:: PyObject* _PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg) + + Call a method of the Python object *obj* with a single positional argument + *arg*, where the name of the method is given as a Python string object in + *name*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + .. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) Call a callable Python object *callable*, using diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index e9a23195f414..d57aa54bc466 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -163,6 +163,15 @@ _PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } +static inline PyObject * +_PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg) +{ + assert(arg != NULL); + PyObject *args[2] = {self, arg}; + return _PyObject_VectorcallMethod(name, args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + /* Like PyObject_CallMethod(), but expect a _Py_Identifier* as the method name. */ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, @@ -198,6 +207,15 @@ _PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name) 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } +static inline PyObject * +_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg) +{ + assert(arg != NULL); + PyObject *args[2] = {self, arg}; + return _PyObject_VectorcallMethodId(name, args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +} + PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); /* Guess the size of object 'o' using len(o) or o.__length_hint__(). diff --git a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst b/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst index df0e807e1166..63b355ecdb33 100644 --- a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst +++ b/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst @@ -1,2 +1,2 @@ -Add fast functions for calling methods: :c:func:`_PyObject_VectorcallMethod` -and :c:func:`_PyObject_CallMethodNoArgs` +Add fast functions for calling methods: :c:func:`_PyObject_VectorcallMethod`, +:c:func:`_PyObject_CallMethodNoArgs` and :c:func:`_PyObject_CallMethodOneArg`. diff --git a/Modules/_abc.c b/Modules/_abc.c index 219ea0dd628f..7b5d4180bf87 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -480,7 +480,6 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, /*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/ { PyObject *subtype, *result = NULL, *subclass = NULL; - PyObject *margs[2]; _abc_data *impl = _get_impl(self); if (impl == NULL) { return NULL; @@ -515,16 +514,12 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, } } /* Fall back to the subclass check. */ - margs[0] = self; - margs[1] = subclass; - result = _PyObject_VectorcallMethodId(&PyId___subclasscheck__, margs, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, + subclass); goto end; } - margs[0] = self; - margs[1] = subclass; - result = _PyObject_VectorcallMethodId(&PyId___subclasscheck__, margs, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, + subclass); if (result == NULL) { goto end; } @@ -536,10 +531,8 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, break; case 0: Py_DECREF(result); - margs[0] = self; - margs[1] = subtype; - result = _PyObject_VectorcallMethodId(&PyId___subclasscheck__, margs, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__, + subtype); break; case 1: // Nothing to do. break; @@ -620,8 +613,8 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, } /* 3. Check the subclass hook. */ - ok = _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId___subclasshook__, - subclass, NULL); + ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__, + subclass); if (ok == NULL) { goto end; } diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 6c469d2a2ec5..e9e6c5682d62 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1842,8 +1842,8 @@ register_task(PyObject *task) { _Py_IDENTIFIER(add); - PyObject *res = _PyObject_CallMethodIdObjArgs( - all_tasks, &PyId_add, task, NULL); + PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, + &PyId_add, task); if (res == NULL) { return -1; } @@ -1857,8 +1857,8 @@ unregister_task(PyObject *task) { _Py_IDENTIFIER(discard); - PyObject *res = _PyObject_CallMethodIdObjArgs( - all_tasks, &PyId_discard, task, NULL); + PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, + &PyId_discard, task); if (res == NULL) { return -1; } @@ -2611,13 +2611,11 @@ task_step_impl(TaskObj *task, PyObject *exc) result = _PyGen_Send((PyGenObject*)coro, Py_None); } else { - result = _PyObject_CallMethodIdObjArgs(coro, &PyId_send, - Py_None, NULL); + result = _PyObject_CallMethodIdOneArg(coro, &PyId_send, Py_None); } } else { - result = _PyObject_CallMethodIdObjArgs(coro, &PyId_throw, - exc, NULL); + result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); if (clear_exc) { /* We created 'exc' during this call */ Py_DECREF(exc); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 973a654bf355..bd67c6eeaeed 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1699,7 +1699,7 @@ unpickle(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state)) return NULL; - obj = _PyObject_CallMethodIdObjArgs(typ, &PyId___new__, typ, NULL); + obj = _PyObject_CallMethodIdOneArg(typ, &PyId___new__, typ); if (obj == NULL) return NULL; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 0546368d1df7..19d3d7e848f5 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1237,8 +1237,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) if (tzinfo == Py_None) Py_RETURN_NONE; - result = _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_tzname, - tzinfoarg, NULL); + result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); if (result == NULL || result == Py_None) return result; @@ -1693,8 +1692,7 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) return NULL; } - result = _PyObject_CallMethodIdObjArgs(time, &PyId_struct_time, - args, NULL); + result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); Py_DECREF(time); Py_DECREF(args); return result; @@ -2894,8 +2892,7 @@ date_today(PyObject *cls, PyObject *dummy) * time.time() delivers; if someone were gonzo about optimization, * date.today() could get away with plain C time(). */ - result = _PyObject_CallMethodIdObjArgs(cls, &PyId_fromtimestamp, - time, NULL); + result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); Py_DECREF(time); return result; } @@ -3209,8 +3206,8 @@ date_format(PyDateTime_Date *self, PyObject *args) if (PyUnicode_GetLength(format) == 0) return PyObject_Str((PyObject *)self); - return _PyObject_CallMethodIdObjArgs((PyObject *)self, &PyId_strftime, - format, NULL); + return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, + format); } /* ISO methods. */ @@ -5960,7 +5957,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) temp = (PyObject *)result; result = (PyDateTime_DateTime *) - _PyObject_CallMethodIdObjArgs(tzinfo, &PyId_fromutc, temp, NULL); + _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); Py_DECREF(temp); return result; diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b93ec3d12786..b9b50165bfda 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2679,7 +2679,7 @@ treebuilder_add_subelement(PyObject *element, PyObject *child) } else { PyObject *res; - res = _PyObject_CallMethodIdObjArgs(element, &PyId_append, child, NULL); + res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child); if (res == NULL) return -1; Py_DECREF(res); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 9e7e5f3d0935..86dd277f94c1 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -439,8 +439,8 @@ buffered_dealloc_warn(buffered *self, PyObject *source) { if (self->ok && self->raw) { PyObject *r; - r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn, - source, NULL); + r = _PyObject_CallMethodIdOneArg(self->raw, &PyId__dealloc_warn, + source); if (r) Py_DECREF(r); else @@ -1323,7 +1323,7 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos) goto end; Py_CLEAR(res); } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL); + res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_truncate, pos); if (res == NULL) goto end; /* Reset cached position */ @@ -1467,7 +1467,7 @@ _bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len) raised (see issue #10956). */ do { - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL); + res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_readinto, memobj); } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); if (res == NULL) @@ -1815,7 +1815,7 @@ _bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len) */ do { errno = 0; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL); + res = _PyObject_CallMethodOneArg(self->raw, _PyIO_str_write, memobj); errnum = errno; } while (res == NULL && _PyIO_trap_eintr()); Py_DECREF(memobj); diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 7f784a34c30d..e4cbbfa9bb8c 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -145,8 +145,8 @@ _io_FileIO_close_impl(fileio *self) PyObject *exc, *val, *tb; int rc; _Py_IDENTIFIER(close); - res = _PyObject_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type, - &PyId_close, self, NULL); + res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, + &PyId_close, (PyObject *)self); if (!self->closefd) { self->fd = -1; return res; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index ed1dc005c69a..05911d9222ff 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -977,8 +977,8 @@ _textiowrapper_fix_encoder_state(textio *self) if (cmp == 0) { self->encoding_start_of_stream = 0; - PyObject *res = PyObject_CallMethodObjArgs( - self->encoder, _PyIO_str_setstate, _PyLong_Zero, NULL); + PyObject *res = _PyObject_CallMethodOneArg( + self->encoder, _PyIO_str_setstate, _PyLong_Zero); if (res == NULL) { return -1; } @@ -1155,8 +1155,8 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, PyObject *locale_module = _PyIO_get_locale_module(state); if (locale_module == NULL) goto catch_ImportError; - self->encoding = _PyObject_CallMethodIdObjArgs( - locale_module, &PyId_getpreferredencoding, Py_False, NULL); + self->encoding = _PyObject_CallMethodIdOneArg( + locale_module, &PyId_getpreferredencoding, Py_False); Py_DECREF(locale_module); if (self->encoding == NULL) { catch_ImportError: @@ -1597,8 +1597,7 @@ _textiowrapper_writeflush(textio *self) PyObject *ret; do { - ret = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_write, b, NULL); + ret = _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_write, b); } while (ret == NULL && _PyIO_trap_eintr()); Py_DECREF(b); if (ret == NULL) @@ -1668,8 +1667,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) self->encoding_start_of_stream = 0; } else - b = PyObject_CallMethodObjArgs(self->encoder, - _PyIO_str_encode, text, NULL); + b = _PyObject_CallMethodOneArg(self->encoder, _PyIO_str_encode, text); Py_DECREF(text); if (b == NULL) @@ -1851,9 +1849,9 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) if (chunk_size == NULL) goto fail; - input_chunk = PyObject_CallMethodObjArgs(self->buffer, + input_chunk = _PyObject_CallMethodOneArg(self->buffer, (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), - chunk_size, NULL); + chunk_size); Py_DECREF(chunk_size); if (input_chunk == NULL) goto fail; @@ -2414,8 +2412,8 @@ _textiowrapper_encoder_reset(textio *self, int start_of_stream) self->encoding_start_of_stream = 1; } else { - res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate, - _PyLong_Zero, NULL); + res = _PyObject_CallMethodOneArg(self->encoder, _PyIO_str_setstate, + _PyLong_Zero); self->encoding_start_of_stream = 0; } if (res == NULL) @@ -2554,8 +2552,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) posobj = PyLong_FromOff_t(cookie.start_pos); if (posobj == NULL) goto fail; - res = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_seek, posobj, NULL); + res = _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_seek, posobj); Py_DECREF(posobj); if (res == NULL) goto fail; @@ -2837,7 +2834,7 @@ _io_TextIOWrapper_tell_impl(textio *self) } finally: - res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL); + res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); Py_DECREF(saved_state); if (res == NULL) return NULL; @@ -2851,7 +2848,7 @@ _io_TextIOWrapper_tell_impl(textio *self) if (saved_state) { PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); - res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL); + res = _PyObject_CallMethodIdOneArg(self->decoder, &PyId_setstate, saved_state); _PyErr_ChainExceptions(type, value, traceback); Py_DECREF(saved_state); Py_XDECREF(res); @@ -2878,7 +2875,7 @@ _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) return NULL; Py_DECREF(res); - return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL); + return _PyObject_CallMethodOneArg(self->buffer, _PyIO_str_truncate, pos); } static PyObject * @@ -3055,9 +3052,9 @@ _io_TextIOWrapper_close_impl(textio *self) else { PyObject *exc = NULL, *val, *tb; if (self->finalizing) { - res = _PyObject_CallMethodIdObjArgs(self->buffer, - &PyId__dealloc_warn, - self, NULL); + res = _PyObject_CallMethodIdOneArg(self->buffer, + &PyId__dealloc_warn, + (PyObject *)self); if (res) Py_DECREF(res); else diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index ea5d24f950a1..f27a6dc93a2b 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -204,8 +204,8 @@ _io__WindowsConsoleIO_close_impl(winconsoleio *self) PyObject *exc, *val, *tb; int rc; _Py_IDENTIFIER(close); - res = _PyObject_CallMethodIdObjArgs((PyObject*)&PyRawIOBase_Type, - &PyId_close, self, NULL); + res = _PyObject_CallMethodIdOneArg((PyObject*)&PyRawIOBase_Type, + &PyId_close, self); if (!self->closehandle) { self->handle = INVALID_HANDLE_VALUE; return res; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 0b0928f5cd2f..735c13d03d8f 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5773,7 +5773,7 @@ instantiate(PyObject *cls, PyObject *args) return NULL; } if (func == NULL) { - return _PyObject_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL); + return _PyObject_CallMethodIdOneArg(cls, &PyId___new__, cls); } Py_DECREF(func); } diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 30a9b889a9df..47b8b62cea26 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1185,9 +1185,9 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso return -1; } - uppercase_level = _PyObject_CallMethodIdObjArgs( + uppercase_level = _PyObject_CallMethodIdOneArg( (PyObject *)&PyUnicode_Type, &PyId_upper, - isolation_level, NULL); + isolation_level); if (!uppercase_level) { return -1; } @@ -1648,8 +1648,8 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - uppercase_name = _PyObject_CallMethodIdObjArgs((PyObject *)&PyUnicode_Type, - &PyId_upper, name, NULL); + uppercase_name = _PyObject_CallMethodIdOneArg((PyObject *)&PyUnicode_Type, + &PyId_upper, name); if (!uppercase_name) { goto finally; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 26c90a8a5983..48986c419029 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1507,7 +1507,7 @@ array_array_tofile(arrayobject *self, PyObject *f) bytes = PyBytes_FromStringAndSize(ptr, size); if (bytes == NULL) return NULL; - res = _PyObject_CallMethodIdObjArgs(f, &PyId_write, bytes, NULL); + res = _PyObject_CallMethodIdOneArg(f, &PyId_write, bytes); Py_DECREF(bytes); if (res == NULL) return NULL; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 052ed8878c1c..4de678757b38 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1776,7 +1776,7 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, if (str == NULL) return -1; - wr = _PyObject_CallMethodIdObjArgs(self->stream, &PyId_write, str, NULL); + wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); Py_DECREF(str); if (wr == NULL) return -1; @@ -1870,7 +1870,7 @@ _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *se if (PyBytes_Size(pwrt) > 0) { PyObject *wr; - wr = _PyObject_CallMethodIdObjArgs(self->stream, &PyId_write, pwrt); + wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); if (wr == NULL) { Py_DECREF(pwrt); return NULL; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 422f4b0230ba..b6205d93ca14 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4159,7 +4159,7 @@ dictviews_sub(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_difference_update, other, NULL); + tmp = _PyObject_CallMethodIdOneArg(result, &PyId_difference_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4179,7 +4179,7 @@ _PyDictView_Intersect(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_intersection_update, other, NULL); + tmp = _PyObject_CallMethodIdOneArg(result, &PyId_intersection_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4199,7 +4199,7 @@ dictviews_or(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_update, other, NULL); + tmp = _PyObject_CallMethodIdOneArg(result, &PyId_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4219,7 +4219,7 @@ dictviews_xor(PyObject* self, PyObject *other) if (result == NULL) return NULL; - tmp = _PyObject_CallMethodIdObjArgs(result, &PyId_symmetric_difference_update, other, NULL); + tmp = _PyObject_CallMethodIdOneArg(result, &PyId_symmetric_difference_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 96021eeccc57..8acf678fc9a4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4145,8 +4145,8 @@ _PyType_GetSlotNames(PyTypeObject *cls) /* Use _slotnames function from the copyreg module to find the slots by this class and its bases. This function will cache the result in __slotnames__. */ - slotnames = _PyObject_CallMethodIdObjArgs(copyreg, &PyId__slotnames, - cls, NULL); + slotnames = _PyObject_CallMethodIdOneArg(copyreg, &PyId__slotnames, + (PyObject *)cls); Py_DECREF(copyreg); if (slotnames == NULL) return NULL; diff --git a/Python/_warnings.c b/Python/_warnings.c index b1762e6bedaf..ecee399db6e8 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -164,7 +164,7 @@ check_matched(PyObject *obj, PyObject *arg) } /* Otherwise assume a regex filter and call its match() method */ - result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL); + result = _PyObject_CallMethodIdOneArg(obj, &PyId_match, arg); if (result == NULL) return -1; diff --git a/Python/ceval.c b/Python/ceval.c index fdd299561c61..7c7359166dad 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2052,7 +2052,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (v == Py_None) retval = Py_TYPE(receiver)->tp_iternext(receiver); else - retval = _PyObject_CallMethodIdObjArgs(receiver, &PyId_send, v, NULL); + retval = _PyObject_CallMethodIdOneArg(receiver, &PyId_send, v); } Py_DECREF(v); if (retval == NULL) { diff --git a/Python/import.c b/Python/import.c index df258751c82e..15f1d9417600 100644 --- a/Python/import.c +++ b/Python/import.c @@ -962,9 +962,8 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, external= PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); if (external != NULL) { - pathobj = _PyObject_CallMethodIdObjArgs(external, - &PyId__get_sourcefile, cpathobj, - NULL); + pathobj = _PyObject_CallMethodIdOneArg( + external, &PyId__get_sourcefile, cpathobj); Py_DECREF(external); } if (pathobj == NULL) @@ -1827,9 +1826,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, */ spec = _PyObject_GetAttrId(mod, &PyId___spec__); if (_PyModuleSpec_IsInitializing(spec)) { - PyObject *value = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__lock_unlock_module, abs_name, - NULL); + PyObject *value = _PyObject_CallMethodIdOneArg( + interp->importlib, &PyId__lock_unlock_module, abs_name); if (value == NULL) { Py_DECREF(spec); goto error; @@ -1968,7 +1966,7 @@ PyImport_ReloadModule(PyObject *m) } } - reloaded_module = _PyObject_CallMethodIdObjArgs(imp, &PyId_reload, m, NULL); + reloaded_module = _PyObject_CallMethodIdOneArg(imp, &PyId_reload, m); Py_DECREF(imp); return reloaded_module; } diff --git a/Python/marshal.c b/Python/marshal.c index b2daff2c8a3b..cb11c8c74ef3 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1653,7 +1653,7 @@ marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file, s = PyMarshal_WriteObjectToString(value, version); if (s == NULL) return NULL; - res = _PyObject_CallMethodIdObjArgs(file, &PyId_write, s, NULL); + res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s); Py_DECREF(s); return res; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index dc198a5d1e05..103a11152412 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -581,7 +581,7 @@ sys_displayhook_unencodable(PyThreadState *tstate, PyObject *outf, PyObject *o) buffer = _PyObject_GetAttrId(outf, &PyId_buffer); if (buffer) { - result = _PyObject_CallMethodIdObjArgs(buffer, &PyId_write, encoded, NULL); + result = _PyObject_CallMethodIdOneArg(buffer, &PyId_write, encoded); Py_DECREF(buffer); Py_DECREF(encoded); if (result == NULL) @@ -3114,9 +3114,7 @@ sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) if (file == NULL) return -1; assert(unicode != NULL); - PyObject *margs[2] = {file, unicode}; - PyObject *result = _PyObject_VectorcallMethodId(&PyId_write, margs, - 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + PyObject *result = _PyObject_CallMethodIdOneArg(file, &PyId_write, unicode); if (result == NULL) { return -1; } From webhook-mailer at python.org Thu Jul 11 10:01:02 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:01:02 -0000 Subject: [Python-checkins] bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) Message-ID: https://github.com/python/cpython/commit/79042ac4348ccc09344014f20dd49401579f8795 commit: 79042ac4348ccc09344014f20dd49401579f8795 branch: master author: Tal Einat committer: GitHub date: 2019-07-11T17:00:34+03:00 summary: bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) files: M Doc/library/select.rst diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 733a91e20b68..8f5a2cea9257 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -480,13 +480,14 @@ Kqueue Objects Create a kqueue object from a given file descriptor. -.. method:: kqueue.control(changelist, max_events[, timeout=None]) -> eventlist +.. method:: kqueue.control(changelist, max_events[, timeout]) -> eventlist Low level interface to kevent - - changelist must be an iterable of kevent object or ``None`` + - changelist must be an iterable of kevent objects or ``None`` - max_events must be 0 or a positive integer - - timeout in seconds (floats possible) + - timeout in seconds (floats possible); the default is ``None``, + to wait forever .. versionchanged:: 3.5 The function is now retried with a recomputed timeout when interrupted by From webhook-mailer at python.org Thu Jul 11 10:16:10 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 14:16:10 -0000 Subject: [Python-checkins] bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) Message-ID: https://github.com/python/cpython/commit/dc0b6af42eca70e520b67d0bcf4dc5278a3f02dd commit: dc0b6af42eca70e520b67d0bcf4dc5278a3f02dd branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-11T07:16:03-07:00 summary: bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) (cherry picked from commit 79042ac4348ccc09344014f20dd49401579f8795) Co-authored-by: Tal Einat files: M Doc/library/select.rst diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 733a91e20b68..8f5a2cea9257 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -480,13 +480,14 @@ Kqueue Objects Create a kqueue object from a given file descriptor. -.. method:: kqueue.control(changelist, max_events[, timeout=None]) -> eventlist +.. method:: kqueue.control(changelist, max_events[, timeout]) -> eventlist Low level interface to kevent - - changelist must be an iterable of kevent object or ``None`` + - changelist must be an iterable of kevent objects or ``None`` - max_events must be 0 or a positive integer - - timeout in seconds (floats possible) + - timeout in seconds (floats possible); the default is ``None``, + to wait forever .. versionchanged:: 3.5 The function is now retried with a recomputed timeout when interrupted by From webhook-mailer at python.org Thu Jul 11 10:16:49 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:16:49 -0000 Subject: [Python-checkins] bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) Message-ID: https://github.com/python/cpython/commit/d3747fd8fa91b768b73b60f2e2a14044e5404afa commit: d3747fd8fa91b768b73b60f2e2a14044e5404afa branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Tal Einat date: 2019-07-11T17:16:45+03:00 summary: bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) (cherry picked from commit 79042ac4348ccc09344014f20dd49401579f8795) Co-authored-by: Tal Einat files: M Doc/library/select.rst diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 5b8fd7ee805c..7d65363e4931 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -480,13 +480,14 @@ Kqueue Objects Create a kqueue object from a given file descriptor. -.. method:: kqueue.control(changelist, max_events[, timeout=None]) -> eventlist +.. method:: kqueue.control(changelist, max_events[, timeout]) -> eventlist Low level interface to kevent - - changelist must be an iterable of kevent object or ``None`` + - changelist must be an iterable of kevent objects or ``None`` - max_events must be 0 or a positive integer - - timeout in seconds (floats possible) + - timeout in seconds (floats possible); the default is ``None``, + to wait forever .. versionchanged:: 3.5 The function is now retried with a recomputed timeout when interrupted by From webhook-mailer at python.org Thu Jul 11 10:17:12 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:17:12 -0000 Subject: [Python-checkins] bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) Message-ID: https://github.com/python/cpython/commit/46c2eff5adca7dc309f077ec65faf95b95c47b43 commit: 46c2eff5adca7dc309f077ec65faf95b95c47b43 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Tal Einat date: 2019-07-11T17:17:08+03:00 summary: bpo-34369: make kqueue.control() docs better reflect that timeout is positional-only (GH-9499) (cherry picked from commit 79042ac4348ccc09344014f20dd49401579f8795) Co-authored-by: Tal Einat files: M Doc/library/select.rst diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 7a080457a05e..b68b32486ad8 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -291,13 +291,14 @@ Kqueue Objects Create a kqueue object from a given file descriptor. -.. method:: kqueue.control(changelist, max_events[, timeout=None]) -> eventlist +.. method:: kqueue.control(changelist, max_events[, timeout]) -> eventlist Low level interface to kevent - - changelist must be an iterable of kevent object or ``None`` + - changelist must be an iterable of kevent objects or ``None`` - max_events must be 0 or a positive integer - - timeout in seconds (floats possible) + - timeout in seconds (floats possible); the default is ``None``, + to wait forever .. _kevent-objects: From webhook-mailer at python.org Thu Jul 11 10:20:21 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:20:21 -0000 Subject: [Python-checkins] bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) Message-ID: https://github.com/python/cpython/commit/9b5ce62cac27fec9dea473865d79c2c654312957 commit: 9b5ce62cac27fec9dea473865d79c2c654312957 branch: master author: Tal Einat committer: GitHub date: 2019-07-11T17:20:14+03:00 summary: bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) files: M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 606de71a6add..9b5364f0c774 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1281,7 +1281,7 @@ def smart_indent_event(self, event): text.delete(first, last) text.mark_set("insert", first) prefix = text.get("insert linestart", "insert") - raw, effective = classifyws(prefix, self.tabwidth) + raw, effective = get_line_indent(prefix, self.tabwidth) if raw == len(prefix): # only whitespace to the left self.reindent_to(effective + self.indentwidth) @@ -1415,7 +1415,7 @@ def indent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = effective + self.indentwidth lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1426,7 +1426,7 @@ def dedent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = max(effective - self.indentwidth, 0) lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1461,7 +1461,7 @@ def tabify_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, tabwidth) + raw, effective = get_line_indent(line, tabwidth) ntabs, nspaces = divmod(effective, tabwidth) lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] self.set_region(head, tail, chars, lines) @@ -1575,8 +1575,8 @@ def _asktabwidth(self): def guess_indent(self): opener, indented = IndentSearcher(self.text, self.tabwidth).run() if opener and indented: - raw, indentsmall = classifyws(opener, self.tabwidth) - raw, indentlarge = classifyws(indented, self.tabwidth) + raw, indentsmall = get_line_indent(opener, self.tabwidth) + raw, indentlarge = get_line_indent(indented, self.tabwidth) else: indentsmall = indentlarge = 0 return indentlarge - indentsmall @@ -1585,23 +1585,16 @@ def guess_indent(self): def index2line(index): return int(float(index)) -# Look at the leading whitespace in s. -# Return pair (# of leading ws characters, -# effective # of leading blanks after expanding -# tabs to width tabwidth) - -def classifyws(s, tabwidth): - raw = effective = 0 - for ch in s: - if ch == ' ': - raw = raw + 1 - effective = effective + 1 - elif ch == '\t': - raw = raw + 1 - effective = (effective // tabwidth + 1) * tabwidth - else: - break - return raw, effective + +_line_indent_re = re.compile(r'[ \t]*') +def get_line_indent(line, tabwidth): + """Return a line's indentation as (# chars, effective # of spaces). + + The effective # of spaces is the length after properly "expanding" + the tabs into spaces, as done by str.expandtabs(tabwidth). + """ + m = _line_indent_re.match(line) + return m.end(), len(m.group().expandtabs(tabwidth)) class IndentSearcher(object): diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 12bc84736683..4af4ff0242d7 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -42,5 +42,66 @@ class dummy(): self.assertEqual(func(dummy, inp), out) +class TestGetLineIndent(unittest.TestCase): + def test_empty_lines(self): + for tabwidth in [1, 2, 4, 6, 8]: + for line in ['', '\n']: + with self.subTest(line=line, tabwidth=tabwidth): + self.assertEqual( + editor.get_line_indent(line, tabwidth=tabwidth), + (0, 0), + ) + + def test_tabwidth_4(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (4, 4)), + ('\ttab test', (1, 4)), + ('\t\tdouble tabs test', (2, 8)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (5, 8)), + (' \t mixed test', (5, 6)), + ('\t mixed test', (5, 8)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 4)), + (' \t mixed test', (3, 5)), + ('\t mixed test', (3, 6)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=4), + expected, + ) + + def test_tabwidth_8(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (8, 8)), + ('\ttab test', (1, 8)), + ('\t\tdouble tabs test', (2, 16)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (9, 16)), + (' \t mixed test', (9, 10)), + ('\t mixed test', (9, 16)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 8)), + (' \t mixed test', (3, 9)), + ('\t mixed test', (3, 10)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=8), + expected, + ) + + if __name__ == '__main__': unittest.main(verbosity=2) From webhook-mailer at python.org Thu Jul 11 10:55:27 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:55:27 -0000 Subject: [Python-checkins] bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) Message-ID: https://github.com/python/cpython/commit/242ad1f375bf564c35cf99cd754b2c5819c4d056 commit: 242ad1f375bf564c35cf99cd754b2c5819c4d056 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Tal Einat date: 2019-07-11T17:55:05+03:00 summary: bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) (cherry picked from commit 9b5ce62cac27fec9dea473865d79c2c654312957) Co-authored-by: Tal Einat files: M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 606de71a6add..9b5364f0c774 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1281,7 +1281,7 @@ def smart_indent_event(self, event): text.delete(first, last) text.mark_set("insert", first) prefix = text.get("insert linestart", "insert") - raw, effective = classifyws(prefix, self.tabwidth) + raw, effective = get_line_indent(prefix, self.tabwidth) if raw == len(prefix): # only whitespace to the left self.reindent_to(effective + self.indentwidth) @@ -1415,7 +1415,7 @@ def indent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = effective + self.indentwidth lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1426,7 +1426,7 @@ def dedent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = max(effective - self.indentwidth, 0) lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1461,7 +1461,7 @@ def tabify_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, tabwidth) + raw, effective = get_line_indent(line, tabwidth) ntabs, nspaces = divmod(effective, tabwidth) lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] self.set_region(head, tail, chars, lines) @@ -1575,8 +1575,8 @@ def _asktabwidth(self): def guess_indent(self): opener, indented = IndentSearcher(self.text, self.tabwidth).run() if opener and indented: - raw, indentsmall = classifyws(opener, self.tabwidth) - raw, indentlarge = classifyws(indented, self.tabwidth) + raw, indentsmall = get_line_indent(opener, self.tabwidth) + raw, indentlarge = get_line_indent(indented, self.tabwidth) else: indentsmall = indentlarge = 0 return indentlarge - indentsmall @@ -1585,23 +1585,16 @@ def guess_indent(self): def index2line(index): return int(float(index)) -# Look at the leading whitespace in s. -# Return pair (# of leading ws characters, -# effective # of leading blanks after expanding -# tabs to width tabwidth) - -def classifyws(s, tabwidth): - raw = effective = 0 - for ch in s: - if ch == ' ': - raw = raw + 1 - effective = effective + 1 - elif ch == '\t': - raw = raw + 1 - effective = (effective // tabwidth + 1) * tabwidth - else: - break - return raw, effective + +_line_indent_re = re.compile(r'[ \t]*') +def get_line_indent(line, tabwidth): + """Return a line's indentation as (# chars, effective # of spaces). + + The effective # of spaces is the length after properly "expanding" + the tabs into spaces, as done by str.expandtabs(tabwidth). + """ + m = _line_indent_re.match(line) + return m.end(), len(m.group().expandtabs(tabwidth)) class IndentSearcher(object): diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 12bc84736683..4af4ff0242d7 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -42,5 +42,66 @@ class dummy(): self.assertEqual(func(dummy, inp), out) +class TestGetLineIndent(unittest.TestCase): + def test_empty_lines(self): + for tabwidth in [1, 2, 4, 6, 8]: + for line in ['', '\n']: + with self.subTest(line=line, tabwidth=tabwidth): + self.assertEqual( + editor.get_line_indent(line, tabwidth=tabwidth), + (0, 0), + ) + + def test_tabwidth_4(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (4, 4)), + ('\ttab test', (1, 4)), + ('\t\tdouble tabs test', (2, 8)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (5, 8)), + (' \t mixed test', (5, 6)), + ('\t mixed test', (5, 8)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 4)), + (' \t mixed test', (3, 5)), + ('\t mixed test', (3, 6)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=4), + expected, + ) + + def test_tabwidth_8(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (8, 8)), + ('\ttab test', (1, 8)), + ('\t\tdouble tabs test', (2, 16)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (9, 16)), + (' \t mixed test', (9, 10)), + ('\t mixed test', (9, 16)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 8)), + (' \t mixed test', (3, 9)), + ('\t mixed test', (3, 10)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=8), + expected, + ) + + if __name__ == '__main__': unittest.main(verbosity=2) From webhook-mailer at python.org Thu Jul 11 10:58:11 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 11 Jul 2019 14:58:11 -0000 Subject: [Python-checkins] bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) Message-ID: https://github.com/python/cpython/commit/a2cf88efc417f1991720856f6913d16660e48941 commit: a2cf88efc417f1991720856f6913d16660e48941 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Tal Einat date: 2019-07-11T17:57:45+03:00 summary: bpo-36390: simplify classifyws(), rename it and add unit tests (GH-14500) (cherry picked from commit 9b5ce62cac27fec9dea473865d79c2c654312957) Co-authored-by: Tal Einat files: M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_editor.py diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 606de71a6add..9b5364f0c774 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -1281,7 +1281,7 @@ def smart_indent_event(self, event): text.delete(first, last) text.mark_set("insert", first) prefix = text.get("insert linestart", "insert") - raw, effective = classifyws(prefix, self.tabwidth) + raw, effective = get_line_indent(prefix, self.tabwidth) if raw == len(prefix): # only whitespace to the left self.reindent_to(effective + self.indentwidth) @@ -1415,7 +1415,7 @@ def indent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = effective + self.indentwidth lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1426,7 +1426,7 @@ def dedent_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, self.tabwidth) + raw, effective = get_line_indent(line, self.tabwidth) effective = max(effective - self.indentwidth, 0) lines[pos] = self._make_blanks(effective) + line[raw:] self.set_region(head, tail, chars, lines) @@ -1461,7 +1461,7 @@ def tabify_region_event(self, event): for pos in range(len(lines)): line = lines[pos] if line: - raw, effective = classifyws(line, tabwidth) + raw, effective = get_line_indent(line, tabwidth) ntabs, nspaces = divmod(effective, tabwidth) lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:] self.set_region(head, tail, chars, lines) @@ -1575,8 +1575,8 @@ def _asktabwidth(self): def guess_indent(self): opener, indented = IndentSearcher(self.text, self.tabwidth).run() if opener and indented: - raw, indentsmall = classifyws(opener, self.tabwidth) - raw, indentlarge = classifyws(indented, self.tabwidth) + raw, indentsmall = get_line_indent(opener, self.tabwidth) + raw, indentlarge = get_line_indent(indented, self.tabwidth) else: indentsmall = indentlarge = 0 return indentlarge - indentsmall @@ -1585,23 +1585,16 @@ def guess_indent(self): def index2line(index): return int(float(index)) -# Look at the leading whitespace in s. -# Return pair (# of leading ws characters, -# effective # of leading blanks after expanding -# tabs to width tabwidth) - -def classifyws(s, tabwidth): - raw = effective = 0 - for ch in s: - if ch == ' ': - raw = raw + 1 - effective = effective + 1 - elif ch == '\t': - raw = raw + 1 - effective = (effective // tabwidth + 1) * tabwidth - else: - break - return raw, effective + +_line_indent_re = re.compile(r'[ \t]*') +def get_line_indent(line, tabwidth): + """Return a line's indentation as (# chars, effective # of spaces). + + The effective # of spaces is the length after properly "expanding" + the tabs into spaces, as done by str.expandtabs(tabwidth). + """ + m = _line_indent_re.match(line) + return m.end(), len(m.group().expandtabs(tabwidth)) class IndentSearcher(object): diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index 12bc84736683..4af4ff0242d7 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -42,5 +42,66 @@ class dummy(): self.assertEqual(func(dummy, inp), out) +class TestGetLineIndent(unittest.TestCase): + def test_empty_lines(self): + for tabwidth in [1, 2, 4, 6, 8]: + for line in ['', '\n']: + with self.subTest(line=line, tabwidth=tabwidth): + self.assertEqual( + editor.get_line_indent(line, tabwidth=tabwidth), + (0, 0), + ) + + def test_tabwidth_4(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (4, 4)), + ('\ttab test', (1, 4)), + ('\t\tdouble tabs test', (2, 8)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (5, 8)), + (' \t mixed test', (5, 6)), + ('\t mixed test', (5, 8)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 4)), + (' \t mixed test', (3, 5)), + ('\t mixed test', (3, 6)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=4), + expected, + ) + + def test_tabwidth_8(self): + # (line, (raw, effective)) + tests = (('no spaces', (0, 0)), + # Internal space isn't counted. + (' space test', (8, 8)), + ('\ttab test', (1, 8)), + ('\t\tdouble tabs test', (2, 16)), + # Different results when mixing tabs and spaces. + (' \tmixed test', (9, 16)), + (' \t mixed test', (9, 10)), + ('\t mixed test', (9, 16)), + # Spaces not divisible by tabwidth. + (' \tmixed test', (3, 8)), + (' \t mixed test', (3, 9)), + ('\t mixed test', (3, 10)), + # Only checks spaces and tabs. + ('\nnewline test', (0, 0))) + + for line, expected in tests: + with self.subTest(line=line): + self.assertEqual( + editor.get_line_indent(line, tabwidth=8), + expected, + ) + + if __name__ == '__main__': unittest.main(verbosity=2) From webhook-mailer at python.org Thu Jul 11 11:58:01 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Thu, 11 Jul 2019 15:58:01 -0000 Subject: [Python-checkins] bpo-29548: no longer use PyEval_Call* functions (GH-14683) Message-ID: https://github.com/python/cpython/commit/1dbd084f1f68d7293718b663df675cfbd0c65712 commit: 1dbd084f1f68d7293718b663df675cfbd0c65712 branch: master author: Jeroen Demeyer committer: Inada Naoki date: 2019-07-12T00:57:32+09:00 summary: bpo-29548: no longer use PyEval_Call* functions (GH-14683) files: M Modules/pyexpat.c M Modules/signalmodule.c M Objects/call.c M Python/codecs.c diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 3d193e717c88..b0096e664780 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -208,7 +208,7 @@ call_with_frame(const char *funcname, int lineno, PyObject* func, PyObject* args { PyObject *res; - res = PyEval_CallObject(func, args); + res = PyObject_Call(func, args, NULL); if (res == NULL) { _PyTraceback_Add(funcname, __FILE__, lineno); XML_StopParser(self->itself, XML_FALSE); diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 7698984ff3af..95569b931d60 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1667,8 +1667,7 @@ _PyErr_CheckSignals(void) _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); if (arglist) { - result = PyEval_CallObject(Handlers[i].func, - arglist); + result = PyObject_Call(Handlers[i].func, arglist, NULL); Py_DECREF(arglist); } if (!result) { diff --git a/Objects/call.c b/Objects/call.c index df90595d6c6a..7d917891bc0c 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -457,7 +457,16 @@ PyEval_CallObjectWithKeywords(PyObject *callable, PyObject * PyObject_CallObject(PyObject *callable, PyObject *args) { - return PyEval_CallObjectWithKeywords(callable, args, NULL); + assert(!PyErr_Occurred()); + if (args == NULL) { + return _PyObject_CallNoArg(callable); + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, + "argument list must be a tuple"); + return NULL; + } + return PyObject_Call(callable, args, NULL); } diff --git a/Python/codecs.c b/Python/codecs.c index 75b60ec6bd77..4f38b33e0b76 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -416,7 +416,7 @@ _PyCodec_EncodeInternal(PyObject *object, if (args == NULL) goto onError; - result = PyEval_CallObject(encoder, args); + result = PyObject_Call(encoder, args, NULL); if (result == NULL) { wrap_codec_error("encoding", encoding); goto onError; @@ -462,7 +462,7 @@ _PyCodec_DecodeInternal(PyObject *object, if (args == NULL) goto onError; - result = PyEval_CallObject(decoder,args); + result = PyObject_Call(decoder, args, NULL); if (result == NULL) { wrap_codec_error("decoding", encoding); goto onError; From webhook-mailer at python.org Thu Jul 11 13:31:54 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 17:31:54 -0000 Subject: [Python-checkins] closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) Message-ID: https://github.com/python/cpython/commit/7cbef72902f32866a416ca6c4e732af4541951b8 commit: 7cbef72902f32866a416ca6c4e732af4541951b8 branch: master author: Mariatta committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-11T10:31:19-07:00 summary: closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) https://bugs.python.org/issue37554 files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 519d5581603b..c74d687f08fb 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2098,7 +2098,7 @@ features: On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. - On Unix, if *src* is a file and *dst* is a directory or vice-versa, anq:q + On Unix, if *src* is a file and *dst* is a directory or vice-versa, an :exc:`IsADirectoryError` or a :exc:`NotADirectoryError` will be raised respectively. If both are directories and *dst* is empty, *dst* will be silently replaced. If *dst* is a non-empty directory, an :exc:`OSError` From webhook-mailer at python.org Thu Jul 11 13:45:41 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 17:45:41 -0000 Subject: [Python-checkins] closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) Message-ID: https://github.com/python/cpython/commit/107171500d7d6e60f463eeb4db492c0ae292a669 commit: 107171500d7d6e60f463eeb4db492c0ae292a669 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-11T10:45:36-07:00 summary: closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) https://bugs.python.org/issue37554 (cherry picked from commit 7cbef72902f32866a416ca6c4e732af4541951b8) Co-authored-by: Mariatta files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 519d5581603b..c74d687f08fb 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2098,7 +2098,7 @@ features: On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. - On Unix, if *src* is a file and *dst* is a directory or vice-versa, anq:q + On Unix, if *src* is a file and *dst* is a directory or vice-versa, an :exc:`IsADirectoryError` or a :exc:`NotADirectoryError` will be raised respectively. If both are directories and *dst* is empty, *dst* will be silently replaced. If *dst* is a non-empty directory, an :exc:`OSError` From webhook-mailer at python.org Thu Jul 11 13:48:06 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 17:48:06 -0000 Subject: [Python-checkins] closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) Message-ID: https://github.com/python/cpython/commit/71435f685c0423f878946e584f4b9eb01233d332 commit: 71435f685c0423f878946e584f4b9eb01233d332 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-11T10:48:00-07:00 summary: closes bpo-37554: Remove `q:q` in os.rst documentation (GH-14692) https://bugs.python.org/issue37554 (cherry picked from commit 7cbef72902f32866a416ca6c4e732af4541951b8) Co-authored-by: Mariatta files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 24f14480ae04..5572b62420fe 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2056,7 +2056,7 @@ features: On Windows, if *dst* exists a :exc:`FileExistsError` is always raised. - On Unix, if *src* is a file and *dst* is a directory or vice-versa, anq:q + On Unix, if *src* is a file and *dst* is a directory or vice-versa, an :exc:`IsADirectoryError` or a :exc:`NotADirectoryError` will be raised respectively. If both are directories and *dst* is empty, *dst* will be silently replaced. If *dst* is a non-empty directory, an :exc:`OSError` From webhook-mailer at python.org Thu Jul 11 14:04:19 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 18:04:19 -0000 Subject: [Python-checkins] bpo-37558: Shared memory tests are failing due to double slashes (GH-14703) Message-ID: https://github.com/python/cpython/commit/4737265622251756a9480ab84af2442b6b986850 commit: 4737265622251756a9480ab84af2442b6b986850 branch: master author: Jakub Kul?k committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-11T11:04:09-07:00 summary: bpo-37558: Shared memory tests are failing due to double slashes (GH-14703) With the addition of shared memory into Python 3.8, we now have three tests failing on Solaris, namely `test_multiprocessing_fork`, `test_multiprocessing_forkserver` and `test_multiprocessing_spawn`. The reason seems to be incorrect name handling which results in two slashes being prepended. https://bugs.python.org/issue37558 files: A Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst M Lib/test/_test_multiprocessing.py diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 9a39f385952f..2fe0def2bcd2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3990,7 +3990,7 @@ def test_shared_memory_cleaned_after_process_termination(self): # Create a shared_memory segment, and send the segment name sm = shared_memory.SharedMemory(create=True, size=10) - sys.stdout.write(sm._name + '\\n') + sys.stdout.write(sm.name + '\\n') sys.stdout.flush() time.sleep(100) ''' diff --git a/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst b/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst new file mode 100644 index 000000000000..9f393d71a3f2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst @@ -0,0 +1 @@ +Fix test_shared_memory_cleaned_after_process_termination name handling From webhook-mailer at python.org Thu Jul 11 14:38:59 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 18:38:59 -0000 Subject: [Python-checkins] bpo-37558: Shared memory tests are failing due to double slashes (GH-14703) Message-ID: https://github.com/python/cpython/commit/3d58b78481e0238593f85cc182b798fe3b77648c commit: 3d58b78481e0238593f85cc182b798fe3b77648c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-11T11:38:37-07:00 summary: bpo-37558: Shared memory tests are failing due to double slashes (GH-14703) With the addition of shared memory into Python 3.8, we now have three tests failing on Solaris, namely `test_multiprocessing_fork`, `test_multiprocessing_forkserver` and `test_multiprocessing_spawn`. The reason seems to be incorrect name handling which results in two slashes being prepended. https://bugs.python.org/issue37558 (cherry picked from commit 4737265622251756a9480ab84af2442b6b986850) Co-authored-by: Jakub Kul?k files: A Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst M Lib/test/_test_multiprocessing.py diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 9a39f385952f..2fe0def2bcd2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3990,7 +3990,7 @@ def test_shared_memory_cleaned_after_process_termination(self): # Create a shared_memory segment, and send the segment name sm = shared_memory.SharedMemory(create=True, size=10) - sys.stdout.write(sm._name + '\\n') + sys.stdout.write(sm.name + '\\n') sys.stdout.flush() time.sleep(100) ''' diff --git a/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst b/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst new file mode 100644 index 000000000000..9f393d71a3f2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst @@ -0,0 +1 @@ +Fix test_shared_memory_cleaned_after_process_termination name handling From webhook-mailer at python.org Thu Jul 11 17:57:54 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 11 Jul 2019 21:57:54 -0000 Subject: [Python-checkins] Remove redundant check from arraymodule b_getitem (GH-14676) Message-ID: https://github.com/python/cpython/commit/13ab570febac64bb55fb46d866a9ba5a46ab8902 commit: 13ab570febac64bb55fb46d866a9ba5a46ab8902 branch: master author: Disconnect3d committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-11T14:57:42-07:00 summary: Remove redundant check from arraymodule b_getitem (GH-14676) The `arraymodule`'s `b_getitem` function returns a `PyLong` converted from `arrayobject`'s array, by dereferencing a pointer to `char`. When the `char` type is `signed char`, the `if (x >= 128) x -= 256;` comparison/code is redundant because a `signed char` will have a value of `[-128, 127]` and so `x` will never be greater or equal than 128. This check was indeed needed for situations where a given compiler would assume `char` being `unsigned char` which would make `x` in `[0, 256]` range. However, the check can be removed if we cast the `ob_item` into a signed char pointer (`signed char*`) instead of `char*`. This PR/commit introduces this change. files: M Modules/arraymodule.c diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 48986c419029..6aa981daca1d 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -185,9 +185,7 @@ in bounds; that's the responsibility of the caller. static PyObject * b_getitem(arrayobject *ap, Py_ssize_t i) { - long x = ((char *)ap->ob_item)[i]; - if (x >= 128) - x -= 256; + long x = ((signed char *)ap->ob_item)[i]; return PyLong_FromLong(x); } From webhook-mailer at python.org Thu Jul 11 22:18:16 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 12 Jul 2019 02:18:16 -0000 Subject: [Python-checkins] closes bpo-37566: Remove _realsocket from socket.py. (GH-14711) Message-ID: https://github.com/python/cpython/commit/c8e7146de257930ea8d0d4aa74b3a64fcaa79d4b commit: c8e7146de257930ea8d0d4aa74b3a64fcaa79d4b branch: master author: Hai Shi committer: Benjamin Peterson date: 2019-07-11T19:17:52-07:00 summary: closes bpo-37566: Remove _realsocket from socket.py. (GH-14711) files: M Lib/socket.py diff --git a/Lib/socket.py b/Lib/socket.py index 0dd8ec70e168..3016b03104d4 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -104,8 +104,6 @@ def _intenum_converter(value, enum_klass): except ValueError: return value -_realsocket = socket - # WSA error codes if sys.platform.lower().startswith("win"): errorTab = {} From webhook-mailer at python.org Mon Jul 1 07:29:19 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Mon, 01 Jul 2019 11:29:19 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: bpo-37221: Add PyCode_NewWithPosOnlyArgs to be used internally and set PyCode_New as a compatibility wrapper (GH-13959) (#14505) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/cb083f7cdf604c1d9d264f387f9e8846bc95= 3eb3 commit: cb083f7cdf604c1d9d264f387f9e8846bc953eb3 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.co= m> committer: =C5=81ukasz Langa date: 2019-07-01T13:29:14+02:00 summary: bpo-37221: Add PyCode_NewWithPosOnlyArgs to be used internally and set PyCode= _New as a compatibility wrapper (GH-13959) (#14505) Add PyCode_NewEx to be used internally and set PyCode_New as a compatibility = wrapper (cherry picked from commit 4a2edc34a405150d0b23ecfdcb401e7cf59f4650) Co-authored-by: Pablo Galindo 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. =20 Return the number of free variables in *co*. =20 -.. c:function:: PyCodeObject* PyCode_New(int argcount, int posonlyargcount, = int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, Py= Object *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyOb= ject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject= *lnotab) +.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, i= nt nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObj= ect *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObj= ect *filename, PyObject *name, int firstlineno, PyObject *lnotab) =20 - 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:`57= 0`. - The first parameter (*argcount*) now represents the total number of po= sitional arguments, - including positional-only. + Return a new code object. If you need a dummy code object to create a fr= ame, + use :c:func:`PyCode_NewEmpty` instead. Calling :c:func:`PyCode_New` dire= ctly + can bind you to a precise Python version since the definition of the byte= code + changes often. =20 .. audit-event:: code.__new__ code,filename,name,argcount,posonlyargcount= ,kwonlyargcount,nlocals,stacksize,flags c.PyCode_New =20 +.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int po= sonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyO= bject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject = *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstl= ineno, 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 ch= ar *funcname, int firstlineno) =20 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: =20 +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 8c2f80ce24e0..f423765c8917 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1042,6 +1042,11 @@ Build and C API Changes allocation or deallocation may need to be adjusted. (Contributed by Eddie Elizondo in :issue:`35810`.) =20 +* 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`.) + =20 Deprecated =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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; =20 /* 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=09 @@ -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; } =20 - 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 kwonlyargco= unt, + int nlocals, int stacksize, int flags, + PyObject *code, PyObject *consts, PyObject *names, + PyObject *varnames, PyObject *freevars, PyObject *= cellvars, + PyObject *filename, PyObject *name, int firstlinen= o, + PyObject *lnotab) { PyCodeObject *co; Py_ssize_t *cell2arg =3D NULL; @@ -243,6 +242,20 @@ PyCode_New(int argcount, int posonlyargcount, int kwonly= argcount, return co; } =20 +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 *funcnam= e, int firstlineno) if (filename_ob =3D=3D NULL) goto failed; =20 - result =3D PyCode_New(0, /* argcount */ + result =3D PyCode_NewWithPosOnlyArgs( + 0, /* argcount */ 0, /* posonlyargcount */ 0, /* kwonlyargcount */ 0, /* nlocals */ @@ -492,12 +506,14 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *= kw) if (ourcellvars =3D=3D NULL) goto cleanup; =20 - co =3D (PyObject *)PyCode_New(argcount, posonlyargcount, kwonlyargcount, - nlocals, stacksize, flags, - code, consts, ournames, ourvarnames, - ourfreevars, ourcellvars, filename, - name, firstlineno, lnotab); - cleanup: + co =3D (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount, + kwonlyargcount, + nlocals, stacksize, flags, + code, consts, ournames, + ourvarnames, ourfreevars, + ourcellvars, filename, + name, firstlineno, lnotab); + cleanup:=20 Py_XDECREF(ournames); Py_XDECREF(ourvarnames); Py_XDECREF(ourfreevars); @@ -625,7 +641,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, =20 #undef CHECK_INT_ARG =20 - 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 =3D 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 =3D PyCode_NewWithPosOnlyArgs(posonlyargcount+posorkeywordargcount, + posonlyargcount, kwonlyargcount, nlocals_= int,=20 + maxdepth, flags, bytecode, consts, names, + varnames, freevars, cellvars, c->c_filena= me, + c->u->u_name, c->u->u_firstlineno, a->a_l= notab); 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 =3D=3D NULL) goto code_error; =20 - v =3D (PyObject *) PyCode_New( + v =3D (PyObject *) PyCode_NewWithPosOnlyArgs( argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, From webhook-mailer at python.org Tue Jul 2 07:32:47 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 02 Jul 2019 11:32:47 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Stop using Argument Clinic for dict_pop (GH-13935) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/d4c664736e43284405100d98d516fa269a64= 7461 commit: d4c664736e43284405100d98d516fa269a647461 branch: 3.8 author: Inada Naoki committer: =C5=81ukasz Langa date: 2019-07-02T13:32:43+02:00 summary: Stop using Argument Clinic for dict_pop (GH-13935) files: M Objects/clinic/dictobject.c.h M Objects/dictobject.c diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index b87244d87348..8d5493330835 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -116,42 +116,6 @@ dict_setdefault(PyDictObject *self, PyObject *const *arg= s, Py_ssize_t nargs) return return_value; } =20 -PyDoc_STRVAR(dict_pop__doc__, -"pop($self, key, default=3DNone, /)\n" -"--\n" -"\n" -"Remove specified key and return the corresponding value.\n" -"\n" -"If key is not found, default is returned if given, otherwise KeyError is ra= ised"); - -#define DICT_POP_METHODDEF \ - {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__d= oc__}, - -static PyObject * -dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value); - -static PyObject * -dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *return_value =3D NULL; - PyObject *key; - PyObject *default_value =3D NULL; - - if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { - goto exit; - } - key =3D args[0]; - if (nargs < 2) { - goto skip_optional; - } - default_value =3D args[1]; -skip_optional: - return_value =3D dict_pop_impl(self, key, default_value); - -exit: - return return_value; -} - PyDoc_STRVAR(dict_popitem__doc__, "popitem($self, /)\n" "--\n" @@ -190,4 +154,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED= (ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=3D0fd5cafc61a51d3c input=3Da9049054013a= 1b77]*/ +/*[clinic end generated code: output=3D676532dcc941d399 input=3Da9049054013a= 1b77]*/ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 0cc144375006..e417cd2119c6 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2987,23 +2987,37 @@ dict_clear(PyDictObject *mp, PyObject *Py_UNUSED(igno= red)) Py_RETURN_NONE; } =20 -/*[clinic input] -dict.pop - - key: object - default: object =3D NULL - / +/* +We don't use Argument Clinic for dict.pop because it doesn't support +custom signature for now. +*/ +PyDoc_STRVAR(dict_pop__doc__, +"D.pop(k[,d]) -> v, remove specified key and return the corresponding value.= \n\ +If key is not found, d is returned if given, otherwise KeyError is raised"); =20 -Remove specified key and return the corresponding value. - -If key is not found, default is returned if given, otherwise KeyError is rai= sed -[clinic start generated code]*/ +#define DICT_POP_METHODDEF \ + {"pop", (PyCFunction)(void(*)(void))dict_pop, METH_FASTCALL, dict_pop__d= oc__}, =20 static PyObject * -dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value) -/*[clinic end generated code: output=3D3abb47b89f24c21c input=3D016f6a000e4e= 633b]*/ +dict_pop(PyDictObject *self, PyObject *const *args, Py_ssize_t nargs) { - return _PyDict_Pop((PyObject*)self, key, default_value); + PyObject *return_value =3D NULL; + PyObject *key; + PyObject *default_value =3D NULL; + + if (!_PyArg_CheckPositional("pop", nargs, 1, 2)) { + goto exit; + } + key =3D args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value =3D args[1]; +skip_optional: + return_value =3D _PyDict_Pop((PyObject*)self, key, default_value); + +exit: + return return_value; } =20 /*[clinic input] From webhook-mailer at python.org Thu Jul 4 17:47:48 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Thu, 04 Jul 2019 21:47:48 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.8.0b2 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/21dd01dad7b6b38d4fd40b37d65f1ac7203e= c4e6 commit: 21dd01dad7b6b38d4fd40b37d65f1ac7203ec4e6 branch: 3.8 author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2019-07-04T12:50:19+02:00 summary: Python 3.8.0b2 files: A Misc/NEWS.d/3.8.0b2.rst D Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst D Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst D Misc/NEWS.d/next/C API/2019-06-07-10-47-37.bpo-37191.iGL1_K.rst D Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst D Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst D Misc/NEWS.d/next/C API/2019-06-12-11-45-36.bpo-37221.RhP1E7.rst D Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst D Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst D Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974.wdzzym.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922.EMZ3TF.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316.LytDX_.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224.FHWPGv.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214.hIiHeD.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417.VsZeHL.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst D Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst D Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst D Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst D Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst D Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst D Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst D Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst D Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst D Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst D Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst D Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst D Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst D Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst D Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst D Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst D Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst D Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst D Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst D Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst D Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst D Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst D Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst D Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst D Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst D Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst D Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst D Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst D Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst D Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst D Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst D Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst D Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst D Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst D Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst D Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst D Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst D Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst D Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst D Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst D Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst D Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst D Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst D Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst D Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst D Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst D Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst D Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst D Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst D Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst D Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst D Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst D Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst D Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst D Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst D Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst D Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst D Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst D Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst D Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst D Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst D Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst D Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst D Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst D Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst D Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst D Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst D Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst D Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst D Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst D Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst D Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst D Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst D Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 4a52f833a525..bb31b47bddd6 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 =20 /* Version as a string */ -#define PY_VERSION "3.8.0b1+" +#define PY_VERSION "3.8.0b2" /*--end constants--*/ =20 /* Version as a single 4-byte hex number, e.g. 0x010502B2 =3D=3D 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 1fb19f241ac3..636219108342 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Jun 4 19:40:37 2019 +# Autogenerated by Sphinx on Thu Jul 4 12:44:09 2019 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -3758,6 +3758,8 @@ '\n' " import pdb; pdb.Pdb(skip=3D['django.*']).set_trace()\n" '\n' + ' Raises an auditing event "pdb.Pdb" with no arguments.\n' + '\n' ' New in version 3.1: The *skip* argument.\n' '\n' ' New in version 3.2: The *nosigint* argument. Previously, a= ' @@ -4289,7 +4291,14 @@ 'section The standard type hierarchy. (To summarize, the key type\= n' 'should be *hashable*, which excludes all mutable objects.) Clashe= s\n' 'between duplicate keys are not detected; the last datum (textually= \n' - 'rightmost in the display) stored for a given key value prevails.\n= ', + 'rightmost in the display) stored for a given key value prevails.\n' + '\n' + 'Changed in version 3.8: Prior to Python 3.8, in dict ' + 'comprehensions,\n' + 'the evaluation order of key and value was not well-defined. In\n' + 'CPython, the value was evaluated before the key. Starting with ' + '3.8,\n' + 'the key is evaluated before the value, as proposed by **PEP 572**.= \n', 'dynamic-features': 'Interaction with dynamic features\n' '*********************************\n' '\n' diff --git a/Misc/NEWS.d/3.8.0b2.rst b/Misc/NEWS.d/3.8.0b2.rst new file mode 100644 index 000000000000..f462e753956b --- /dev/null +++ b/Misc/NEWS.d/3.8.0b2.rst @@ -0,0 +1,933 @@ +.. bpo: 37363 +.. date: 2019-07-01-10-31-14 +.. nonce: fSjatj +.. release date: 2019-07-04 +.. section: Security + +Adds audit events for the range of supported run commands (see +:ref:`using-on-general`). + +.. + +.. bpo: 37463 +.. date: 2019-07-01-08-46-14 +.. nonce: 1CHwjE +.. section: Security + +ssl.match_hostname() no longer accepts IPv4 addresses with additional text +after the address and only quad-dotted notation without trailing +whitespaces. Some inet_aton() implementations ignore whitespace and all data +after whitespace, e.g. '127.0.0.1 whatever'. + +.. + +.. bpo: 37363 +.. date: 2019-06-21-15-58-59 +.. nonce: diouyl +.. section: Security + +Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, +:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, +:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, +:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, +:func:`os.scandir` and :func:`breakpoint`. + +.. + +.. bpo: 37364 +.. date: 2019-06-21-14-42-53 +.. nonce: IIRc2s +.. section: Security + +:func:`io.open_code` is now used when reading :file:`.pth` files. + +.. + +.. bpo: 34631 +.. date: 2019-06-17-09-34-25 +.. nonce: DBfM4j +.. section: Security + +Updated OpenSSL to 1.1.1c in Windows installer + +.. + +.. bpo: 37467 +.. date: 2019-07-01-12-22-44 +.. nonce: u-XyEu +.. section: Core and Builtins + +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. + +.. + +.. bpo: 37417 +.. date: 2019-06-26-18-41-00 +.. nonce: VsZeHL +.. section: Core and Builtins + +:meth:`bytearray.extend` now correctly handles errors that arise during +iteration. Patch by Brandt Bucher. + +.. + +.. bpo: 24214 +.. date: 2019-06-22-12-45-20 +.. nonce: hIiHeD +.. section: Core and Builtins + +Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 +incremental decoders. + +.. + +.. bpo: 35224 +.. date: 2019-06-17-06-03-55 +.. nonce: FHWPGv +.. section: Core and Builtins + +Reverse evaluation order of key: value in dict comprehensions as proposed in +PEP 572. I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. + +.. + +.. bpo: 37316 +.. date: 2019-06-17-03-53-16 +.. nonce: LytDX_ +.. section: Core and Builtins + +Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. + +.. + +.. bpo: 37269 +.. date: 2019-06-14-06-32-33 +.. nonce: SjVVAe +.. section: Core and Builtins + +Fix a bug in the peephole optimizer that was not treating correctly constant +conditions with binary operators. Patch by Pablo Galindo. + +.. + +.. bpo: 37213 +.. date: 2019-06-11-11-15-19 +.. nonce: UPii5K +.. section: Core and Builtins + +Handle correctly negative line offsets in the peephole optimizer. Patch by +Pablo Galindo. + +.. + +.. bpo: 37219 +.. date: 2019-06-10-23-18-31 +.. nonce: jPSufq +.. section: Core and Builtins + +Remove errorneous optimization for empty set differences. + +.. + +.. bpo: 36922 +.. date: 2019-06-06-13-59-52 +.. nonce: EMZ3TF +.. section: Core and Builtins + +Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` +instead of only instances of ``function``. + +.. + +.. bpo: 36974 +.. date: 2019-06-06-11-00-55 +.. nonce: wdzzym +.. section: Core and Builtins + +The slot ``tp_vectorcall_offset`` is inherited unconditionally to support +``super().__call__()`` when the base class uses vectorcall. + +.. + +.. bpo: 37160 +.. date: 2019-06-05-09-24-17 +.. nonce: O3IAY3 +.. section: Core and Builtins + +:func:`threading.get_native_id` now also supports NetBSD. + +.. + +.. bpo: 37077 +.. date: 2019-05-28-11-47-44 +.. nonce: S1h0Fc +.. section: Core and Builtins + +Add :func:`threading.get_native_id` support for AIX. Patch by M. Felt + +.. + +.. bpo: 37440 +.. date: 2019-06-28-16-40-17 +.. nonce: t3wX-N +.. section: Library + +http.client now enables TLS 1.3 post-handshake authentication for default +context or if a cert_file is passed to HTTPSConnection. + +.. + +.. bpo: 37437 +.. date: 2019-06-27-20-33-50 +.. nonce: du39_A +.. section: Library + +Update vendorized expat version to 2.2.7. + +.. + +.. bpo: 37428 +.. date: 2019-06-27-13-27-02 +.. nonce: _wcwUd +.. section: Library + +SSLContext.post_handshake_auth =3D 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. + +.. + +.. bpo: 37420 +.. date: 2019-06-26-22-25-05 +.. nonce: CxFJ09 +.. section: Library + +:func:`os.sched_setaffinity` now correctly handles errors that arise during +iteration over its ``mask`` argument. Patch by Brandt Bucher. + +.. + +.. bpo: 37412 +.. date: 2019-06-26-16-28-59 +.. nonce: lx0VjC +.. section: Library + +The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, +rather than the ANSI code page: see :pep:`529` for the rationale. The +function is no longer deprecated on Windows. + +.. + +.. bpo: 29412 +.. date: 2019-06-25-19-27-25 +.. nonce: n4Zqdh +.. section: Library + +Fix IndexError in parsing a header value ending unexpectedly. Patch by +Abhilash Raj. + +.. + +.. bpo: 36546 +.. date: 2019-06-25-05-07-48 +.. nonce: RUcxaK +.. section: Library + +The *dist* argument for statistics.quantiles() is now positional only. The +current name doesn't reflect that the argument can be either a dataset or a +distribution. Marking the parameter as positional avoids confusion and +makes it possible to change the name later. + +.. + +.. bpo: 37394 +.. date: 2019-06-25-02-10-00 +.. nonce: srZ1zx +.. section: Library + +Fix a bug that was causing the :mod:`queue` module to fail if the +accelerator module was not available. Patch by Pablo Galindo. + +.. + +.. bpo: 33972 +.. date: 2019-06-15-14-39-50 +.. nonce: XxnNPw +.. section: Library + +Email with single part but content-type set to ``multipart/*`` doesn't raise +AttributeError anymore. + +.. + +.. bpo: 37280 +.. date: 2019-06-14-13-30-47 +.. nonce: Fxur0F +.. section: Library + +Use threadpool for reading from file for sendfile fallback mode. + +.. + +.. bpo: 37279 +.. date: 2019-06-14-13-25-56 +.. nonce: OHlW6l +.. section: Library + +Fix asyncio sendfile support when sendfile sends extra data in fallback +mode. + +.. + +.. bpo: 19865 +.. date: 2019-06-14-08-30-16 +.. nonce: FRGH4I +.. section: Library + +:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters +on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). + +.. + +.. bpo: 37210 +.. date: 2019-06-12-16-10-50 +.. nonce: r4yMg6 +.. section: Library + +Allow pure Python implementation of :mod:`pickle` to work even when the C +:mod:`_pickle` module is unavailable. + +.. + +.. bpo: 35922 +.. date: 2019-06-11-19-34-29 +.. nonce: rxpzWr +.. section: Library + +Fix :meth:`RobotFileParser.crawl_delay` and +:meth:`RobotFileParser.request_rate` to return ``None`` rather than raise +:exc:`AttributeError` when no relevant rule is defined in the robots.txt +file. Patch by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 35766 +.. date: 2019-06-11-16-41-40 +.. nonce: v1Kj-T +.. section: Library + +Change the format of feature_version to be a (major, minor) tuple. + +.. + +.. bpo: 36607 +.. date: 2019-06-11-13-52-04 +.. nonce: 5_mJkQ +.. section: Library + +Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if +internal tasks weak set is changed by another thread during iteration. + +.. + +.. bpo: 18748 +.. date: 2019-06-11-01-54-19 +.. nonce: ADqCkq +.. section: Library + +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimick :class:`_io.IOBase` finalizer. + +.. + +.. bpo: 36402 +.. date: 2019-06-11-00-35-02 +.. nonce: b0IJVp +.. section: Library + +Fix a race condition at Python shutdown when waiting for threads. Wait until +the Python thread state of all non-daemon threads get deleted (join all +non-daemon threads), rather than just wait until non-daemon Python threads +complete. + +.. + +.. bpo: 34886 +.. date: 2019-06-08-16-03-19 +.. nonce: Ov-pc9 +.. section: Library + +Fix an unintended ValueError from :func:`subprocess.run` when checking for +conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` +args when they were explicitly provided but with `None` values within a +passed in `**kwargs` dict rather than as passed directly by name. Patch +contributed by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 37173 +.. date: 2019-06-08-11-33-48 +.. nonce: 0e_8gS +.. section: Library + +The exception message for ``inspect.getfile()`` now correctly reports the +passed class rather than the builtins module. + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-16-09 +.. nonce: Day_oB +.. section: Library + +Give math.perm() a one argument form that means the same as +math.factorial(). + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-11-34 +.. nonce: b1StSv +.. section: Library + +For math.perm(n, k), let k default to n, giving the same result as +factorial. + +.. + +.. bpo: 37163 +.. date: 2019-06-07-08-18-05 +.. nonce: 36JkUh +.. section: Library + +Deprecated passing ``obj`` argument of :func:`dataclasses.replace` as +keyword argument. + +.. + +.. bpo: 37165 +.. date: 2019-06-05-11-48-19 +.. nonce: V_rwfE +.. section: Library + +Converted _collections._count_elements to use the Argument Clinic. + +.. + +.. bpo: 34767 +.. date: 2019-06-04-23-44-52 +.. nonce: BpDShN +.. section: Library + +Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. + +.. + +.. bpo: 37158 +.. date: 2019-06-04-22-25-38 +.. nonce: JKm15S +.. section: Library + +Speed-up statistics.fmean() by switching from a function to a generator. + +.. + +.. bpo: 37150 +.. date: 2019-06-04-14-44-41 +.. nonce: TTzHxj +.. section: Library + +`argparse._ActionsContainer.add_argument` now throws error, if someone +accidentally pass FileType class object instead of instance of FileType as +`type` argument + +.. + +.. bpo: 35621 +.. date: 2019-05-28-19-03-46 +.. nonce: Abc1lf +.. section: Library + +Support running asyncio subprocesses when execution event loop in a thread +on UNIX. + +.. + +.. bpo: 36520 +.. date: 2019-05-28-02-37-00 +.. nonce: W4tday +.. section: Library + +Lengthy email headers with UTF-8 characters are now properly encoded when +they are folded. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 30835 +.. date: 2019-05-27-15-29-46 +.. nonce: 3FoaWH +.. section: Library + +Fixed a bug in email parsing where a message with invalid bytes in +content-transfer-encoding of a multipart message can cause an +AttributeError. Patch by Andrew Donnellan. + +.. + +.. bpo: 35805 +.. date: 2019-05-17-15-11-08 +.. nonce: E4YwYz +.. section: Library + +Add parser for Message-ID header and add it to default HeaderRegistry. This +should prevent folding of Message-ID using RFC 2048 encoded words. + +.. + +.. bpo: 35070 +.. date: 2019-05-09-18-50-55 +.. nonce: 4vaqNL +.. section: Library + +posix.getgrouplist() now works correctly when the user belongs to +NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 32627 +.. date: 2019-02-03-19-13-08 +.. nonce: b68f64 +.. section: Library + +Fix compile error when ``_uuid`` headers conflicting included. + +.. + +.. bpo: 11122 +.. date: 2018-11-12-19-08-50 +.. nonce: Gj7BQn +.. section: Library + +Distutils won't check for rpmbuild in specified paths only. + +.. + +.. bpo: 4963 +.. date: 2017-08-15-11-24-41 +.. nonce: LRYres +.. section: Library + +Fixed non-deterministic behavior related to mimetypes extension mapping and +module reinitialization. + +.. + +.. bpo: 34903 +.. date: 2019-06-17-09-36-46 +.. nonce: r_wGRc +.. section: Documentation + +Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in +some two-digit formats is optional. Patch by Mike Gleen. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-00-05-28 +.. nonce: ORGRSG +.. section: Tests + +test_distutils.test_build_ext() is now able to remove the temporary +directory on Windows: don't import the newly built C extension ("xx") in the +current process, but test it in a separated process. + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-29-06 +.. nonce: WEfc5A +.. section: Tests + +test_concurrent_futures now cleans up multiprocessing to remove immediately +temporary directories created by multiprocessing.util.get_temp_dir(). + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-20-35 +.. nonce: HCkKWz +.. section: Tests + +test_winconsoleio doesn't leak a temporary file anymore: use +tempfile.TemporaryFile() to remove it when the test completes. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-57-26 +.. nonce: NFH1f0 +.. section: Tests + +multiprocessing tests now explicitly call ``_run_finalizers()`` to +immediately remove temporary directories created by tests. + +.. + +.. bpo: 37199 +.. date: 2019-06-29-23-56-28 +.. nonce: FHDsLf +.. section: Tests + +Fix test failures when IPv6 is unavailable or disabled. + +.. + +.. bpo: 37335 +.. date: 2019-06-28-16-37-52 +.. nonce: o5S2hY +.. section: Tests + +Remove no longer necessary code from c locale coercion tests + +.. + +.. bpo: 37421 +.. date: 2019-06-27-00-37-59 +.. nonce: rVJb3x +.. section: Tests + +Fix test_shutil to no longer leak temporary files. + +.. + +.. bpo: 37411 +.. date: 2019-06-26-15-28-45 +.. nonce: 5lGNhM +.. section: Tests + +Fix test_wsgiref.testEnviron() to no longer depend on the environment +variables (don't fail if "X" variable is set). + +.. + +.. bpo: 37400 +.. date: 2019-06-25-16-02-43 +.. nonce: cx_EWv +.. section: Tests + +Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() to +get groups. Rename also the test to test_chown_gid(). + +.. + +.. bpo: 37359 +.. date: 2019-06-24-10-47-07 +.. nonce: CkdtyO +.. section: Tests + +Add --cleanup option to python3 -m test to remove ``test_python_*`` +directories of previous failed jobs. Add "make cleantest" to run ``python3 +-m test --cleanup``. + +.. + +.. bpo: 37362 +.. date: 2019-06-21-15-47-33 +.. nonce: D3xppx +.. section: Tests + +test_gdb no longer fails if it gets an "unexpected" message on stderr: it +now ignores stderr. The purpose of test_gdb is to test that python-gdb.py +commands work as expected, not to test gdb. + +.. + +.. bpo: 35998 +.. date: 2019-06-14-17-05-49 +.. nonce: yX82oD +.. section: Tests + +Avoid TimeoutError in test_asyncio: test_start_tls_server_1() + +.. + +.. bpo: 37278 +.. date: 2019-06-14-12-21-47 +.. nonce: z0HUOr +.. section: Tests + +Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a +running thread and leaking a reference. + +.. + +.. bpo: 37261 +.. date: 2019-06-13-12-19-56 +.. nonce: NuKFVo +.. section: Tests + +Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method +now ignores unraisable exception raised when clearing its ``unraisable`` +attribute. + +.. + +.. bpo: 37169 +.. date: 2019-06-07-12-23-15 +.. nonce: yfXTFg +.. section: Tests + +Rewrite ``_PyObject_IsFreed()`` unit tests. + +.. + +.. bpo: 37153 +.. date: 2019-06-04-18-30-39 +.. nonce: 711INB +.. section: Tests + +``test_venv.test_mutiprocessing()`` now explicitly calls +``pool.terminate()`` to wait until the pool completes. + +.. + +.. bpo: 28009 +.. date: 2019-04-11-07-59-43 +.. nonce: s85urF +.. section: Tests + +Modify the test_uuid logic to test when a program is available AND can be +used to obtain a MACADDR as basis for an UUID. Patch by M. Felt + +.. + +.. bpo: 37189 +.. date: 2019-06-17-09-40-59 +.. nonce: j5ebdT +.. section: Build + +Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer +exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI +compatibiliy. + +.. + +.. bpo: 10945 +.. date: 2019-07-01-12-38-48 +.. nonce: s0YBHG +.. section: Windows + +Officially drop support for creating bdist_wininst installers on non-Windows +systems. + +.. + +.. bpo: 37369 +.. date: 2019-06-28-09-44-08 +.. nonce: 1iVpxq +.. section: Windows + +Fixes path for :data:`sys.executable` when running from the Microsoft Store. + +.. + +.. bpo: 37351 +.. date: 2019-06-20-12-50-32 +.. nonce: asTnVW +.. section: Windows + +Removes libpython38.a from standard Windows distribution. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-09-05-08 +.. nonce: tdqSmo +.. section: Windows + +Update Windows builds to use SQLite 3.28.0. + +.. + +.. bpo: 37267 +.. date: 2019-06-13-04-15-51 +.. nonce: Ygo5ef +.. section: Windows + +On Windows, :func:`os.dup` no longer creates an inheritable fd when handling +a character file. + +.. + +.. bpo: 36779 +.. date: 2019-06-11-15-41-34 +.. nonce: 0TMw6f +.. section: Windows + +Ensure ``time.tzname`` is correct on Windows when the active code page is +set to CP_UTF7 or CP_UTF8. + +.. + +.. bpo: 34602 +.. date: 2019-07-02-01-06-47 +.. nonce: 10d4wl +.. section: macOS + +Avoid test suite failures on macOS by no longer calling resource.setrlimit +to increase the process stack size limit at runtime. The runtime change is +no longer needed since the interpreter is being built with a larger default +stack size. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-08-58-30 +.. nonce: -CWbfy +.. section: macOS + +Update macOS installer to use SQLite 3.28.0. + +.. + +.. bpo: 34631 +.. date: 2019-06-18-00-30-40 +.. nonce: vSifcv +.. section: macOS + +Updated OpenSSL to 1.1.1c in macOS installer. + +.. + +.. bpo: 37325 +.. date: 2019-06-18-16-40-05 +.. nonce: GssOf1 +.. section: IDLE + +Fix tab focus traversal order for help source and custom run dialogs. + +.. + +.. bpo: 37321 +.. date: 2019-06-17-16-35-30 +.. nonce: zVTTGS +.. section: IDLE + +Both subprocess connection error messages now refer to the 'Startup failure' +section of the IDLE doc. + +.. + +.. bpo: 37177 +.. date: 2019-06-07-00-17-41 +.. nonce: voU6pQ +.. section: IDLE + +Properly 'attach' search dialogs to their main window so that they behave +like other dialogs and do not get hidden behind their main window. + +.. + +.. bpo: 37039 +.. date: 2019-06-04-23-27-33 +.. nonce: FN_fBf +.. section: IDLE + +Adjust "Zoom Height" to individual screens by momemtarily maximizing the +window on first use with a particular screen. Changing screen settings may +invalidate the saved height. While a window is maximized, "Zoom Height" has +no effect. + +.. + +.. bpo: 35763 +.. date: 2019-06-04-20-36-24 +.. nonce: 7XdoWz +.. section: IDLE + +Make calltip reminder about '/' meaning positional-only less obtrusive by +only adding it when there is room on the first line. + +.. + +.. bpo: 5680 +.. date: 2019-06-03-00-39-29 +.. nonce: VCQfOO +.. section: IDLE + +Add 'Run... Customized' to the Run menu to run a module with customized +settings. Any 'command line arguments' entered are added to sys.argv. One +can suppress the normal Shell main module restart. + +.. + +.. bpo: 36763 +.. date: 2019-06-28-15-49-16 +.. nonce: zrmgki +.. section: C API + +Add :func:`PyConfig_SetWideStringList` function. + +.. + +.. bpo: 28805 +.. date: 2019-06-14-14-03-51 +.. nonce: qZC0N_ +.. section: C API + +The :const:`METH_FASTCALL` calling convention has been documented. + +.. + +.. bpo: 37221 +.. date: 2019-06-12-11-45-36 +.. nonce: RhP1E7 +.. section: C API + +``tp_print`` is put back at the end of the ``PyTypeObject`` structure to +restore support for old code (in particular generated by Cython) setting +``tp_print =3D 0``. Note that ``tp_print`` will be removed entirely in Python +3.9. + +.. + +.. bpo: 37221 +.. date: 2019-06-11-02-50-38 +.. nonce: 4tClQT +.. section: C API + +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. + +.. + +.. bpo: 37215 +.. date: 2019-06-10-15-32-34 +.. nonce: yzoNyU +.. section: C API + +Fix dtrace issue introduce by bpo-36842 + +.. + +.. bpo: 37191 +.. date: 2019-06-07-10-47-37 +.. nonce: iGL1_K +.. section: C API + +Python.h does not need compiler support for intermingled declarations (GCC's +``-Wdeclaration-after-statement``), which were added in 3.8.0 Beta 1. Note +that in Python 3.9, intermingled declarations will be needed again. + +.. + +.. bpo: 37170 +.. date: 2019-06-06-08-47-04 +.. nonce: hO_fpM +.. section: C API + +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst = b/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst deleted file mode 100644 index f11f2746e5a0..000000000000 --- a/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer -exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI -compatibiliy. diff --git a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst = b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst deleted file mode 100644 index 7a35c9583d69..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Misc/NEWS.d/next/C API/2019-06-07-10-47-37.bpo-37191.iGL1_K.rst = b/Misc/NEWS.d/next/C API/2019-06-07-10-47-37.bpo-37191.iGL1_K.rst deleted file mode 100644 index 7cb296d33bb5..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-07-10-47-37.bpo-37191.iGL1_K.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Python.h does not need compiler support for intermingled declarations (GCC's -``-Wdeclaration-after-statement``), which were added in 3.8.0 Beta 1. Note -that in Python 3.9, intermingled declarations will be needed again. diff --git a/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst = b/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst deleted file mode 100644 index 58038b21729b..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix dtrace issue introduce by bpo-36842 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 deleted file mode 100644 index 0ea8b9b86788..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -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/Misc/NEWS.d/next/C API/2019-06-12-11-45-36.bpo-37221.RhP1E7.rst = b/Misc/NEWS.d/next/C API/2019-06-12-11-45-36.bpo-37221.RhP1E7.rst deleted file mode 100644 index 96b61dea0d9c..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-12-11-45-36.bpo-37221.RhP1E7.rst=09 +++ /dev/null @@ -1,4 +0,0 @@ -``tp_print`` is put back at the end of the ``PyTypeObject`` structure -to restore support for old code (in particular generated by Cython) -setting ``tp_print =3D 0``. -Note that ``tp_print`` will be removed entirely in Python 3.9. diff --git a/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst = b/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst deleted file mode 100644 index 6d6c4ad4af60..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst=09 +++ /dev/null @@ -1 +0,0 @@ -The :const:`METH_FASTCALL` calling convention has been documented. 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 deleted file mode 100644 index 095d58116385..000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Add :func:`PyConfig_SetWideStringList` function. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077= .S1h0Fc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-3707= 7.S1h0Fc.rst deleted file mode 100644 index 832dfc94ac49..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`threading.get_native_id` support for AIX. -Patch by M. Felt diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160= .O3IAY3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-3716= 0.O3IAY3.rst deleted file mode 100644 index c2fc6804a126..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -:func:`threading.get_native_id` now also supports NetBSD. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974= .wdzzym.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-3697= 4.wdzzym.rst deleted file mode 100644 index 035cdd3d6a9e..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974.wdzzym= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The slot ``tp_vectorcall_offset`` is inherited unconditionally to support -``super().__call__()`` when the base class uses vectorcall. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922= .EMZ3TF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-3692= 2.EMZ3TF.rst deleted file mode 100644 index c2a2ad4e8e73..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922.EMZ3TF= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` i= nstead of only instances of ``function``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219= .jPSufq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-3721= 9.jPSufq.rst deleted file mode 100644 index ef8f52dce678..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Remove errorneous optimization for empty set differences. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213= .UPii5K.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-3721= 3.UPii5K.rst deleted file mode 100644 index b949883da9c2..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Handle correctly negative line offsets in the peephole optimizer. Patch by -Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269= .SjVVAe.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-3726= 9.SjVVAe.rst deleted file mode 100644 index b9b79066774f..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the peephole optimizer that was not treating correctly constant -conditions with binary operators. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316= .LytDX_.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-3731= 6.LytDX_.rst deleted file mode 100644 index 40436d467c85..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316.LytDX_= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224= .FHWPGv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-3522= 4.FHWPGv.rst deleted file mode 100644 index 5a1a79be098a..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224.FHWPGv= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Reverse evaluation order of key: value in dict comprehensions as proposed in= PEP 572. -I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214= .hIiHeD.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-2421= 4.hIiHeD.rst deleted file mode 100644 index 2d70ce05deae..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214.hIiHeD= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 -incremental decoders. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417= .VsZeHL.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-3741= 7.VsZeHL.rst deleted file mode 100644 index f004631e2361..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417.VsZeHL= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`bytearray.extend` now correctly handles errors that arise during iter= ation. -Patch by Brandt Bucher. \ No newline at end of file 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-3746= 7.u-XyEu.rst deleted file mode 100644 index 5e809646b4b8..000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -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/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_w= GRc.rst b/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc= .rst deleted file mode 100644 index 7e277f4ec1ae..000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst +++ /dev/null @@ -1 +0,0 @@ -Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in= some two-digit formats is optional. Patch by Mike Gleen. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst b/= Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst deleted file mode 100644 index 9fc642077488..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add 'Run... Customized' to the Run menu to run a module with customized -settings. Any 'command line arguments' entered are added to sys.argv. -One can suppress the normal Shell main module restart. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst b= /Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst deleted file mode 100644 index c2b6594cc350..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make calltip reminder about '/' meaning positional-only less obtrusive by -only adding it when there is room on the first line. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst b= /Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst deleted file mode 100644 index 71c8c892ba6a..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst +++ /dev/null @@ -1,4 +0,0 @@ -Adjust "Zoom Height" to individual screens by momemtarily maximizing the -window on first use with a particular screen. Changing screen settings -may invalidate the saved height. While a window is maximized, -"Zoom Height" has no effect. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst b= /Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst deleted file mode 100644 index 74e48eef89a6..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Properly 'attach' search dialogs to their main window so that they behave -like other dialogs and do not get hidden behind their main window. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst b= /Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst deleted file mode 100644 index 1321986c5a2c..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Both subprocess connection error messages now refer to the 'Startup failure' -section of the IDLE doc. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst b= /Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst deleted file mode 100644 index edfffbefe884..000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst +++ /dev/null @@ -1 +0,0 @@ -Fix tab focus traversal order for help source and custom run dialogs. diff --git a/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst= b/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst deleted file mode 100644 index 3b060052fd35..000000000000 --- a/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed non-deterministic behavior related to mimetypes extension mapping and -module reinitialization. diff --git a/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rs= t b/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst deleted file mode 100644 index 483906613801..000000000000 --- a/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst +++ /dev/null @@ -1 +0,0 @@ -Distutils won't check for rpmbuild in specified paths only. diff --git a/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rs= t b/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst deleted file mode 100644 index 16708aa5ee54..000000000000 --- a/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst +++ /dev/null @@ -1 +0,0 @@ -Fix compile error when ``_uuid`` headers conflicting included. diff --git a/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rs= t b/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst deleted file mode 100644 index e823f1d469cc..000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst +++ /dev/null @@ -1,2 +0,0 @@ -posix.getgrouplist() now works correctly when the user belongs to -NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. diff --git a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rs= t b/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst deleted file mode 100644 index 2d8c8b3222d0..000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add parser for Message-ID header and add it to default HeaderRegistry. This -should prevent folding of Message-ID using RFC 2048 encoded words. diff --git a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rs= t b/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst deleted file mode 100644 index 019321d6f1d7..000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a bug in email parsing where a message with invalid bytes in -content-transfer-encoding of a multipart message can cause an AttributeError. -Patch by Andrew Donnellan. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rs= t b/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst deleted file mode 100644 index 8171bfe9e2df..000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst +++ /dev/null @@ -1 +0,0 @@ -Lengthy email headers with UTF-8 characters are now properly encoded when th= ey are folded. Patch by Jeffrey Kintscher. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rs= t b/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst deleted file mode 100644 index c492e1de6d5c..000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support running asyncio subprocesses when execution event loop in a thread -on UNIX. diff --git a/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst deleted file mode 100644 index c5be46e1e5d3..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst +++ /dev/null @@ -1 +0,0 @@ -`argparse._ActionsContainer.add_argument` now throws error, if someone accid= entally pass FileType class object instead of instance of FileType as `type` = argument \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst deleted file mode 100644 index 4a5ec4122f94..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst +++ /dev/null @@ -1 +0,0 @@ -Speed-up statistics.fmean() by switching from a function to a generator. diff --git a/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst deleted file mode 100644 index b46bc44506f4..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst +++ /dev/null @@ -1 +0,0 @@ -Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. diff --git a/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rs= t b/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst deleted file mode 100644 index 5430a57ef54c..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst +++ /dev/null @@ -1 +0,0 @@ -Converted _collections._count_elements to use the Argument Clinic. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rs= t b/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst deleted file mode 100644 index 04cf61d3e099..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-07-08-18-05.bpo-37163.36JkUh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecated passing ``obj`` argument of :func:`dataclasses.replace` as -keyword argument. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rs= t b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst deleted file mode 100644 index 77b872319a91..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst +++ /dev/null @@ -1,2 +0,0 @@ -For math.perm(n, k), let k default to n, giving the same result as -factorial. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rs= t b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst deleted file mode 100644 index 500ef54fd615..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Give math.perm() a one argument form that means the same as -math.factorial(). diff --git a/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rs= t b/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst deleted file mode 100644 index e996f97ecddd..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst +++ /dev/null @@ -1 +0,0 @@ -The exception message for ``inspect.getfile()`` now correctly reports the pa= ssed class rather than the builtins module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rs= t b/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst deleted file mode 100644 index 1b5fc3702521..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix an unintended ValueError from :func:`subprocess.run` when checking for -conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` -args when they were explicitly provided but with `None` values within a -passed in `**kwargs` dict rather than as passed directly by name. Patch -contributed by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst deleted file mode 100644 index 3bc537e40ff6..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix a race condition at Python shutdown when waiting for threads. Wait until -the Python thread state of all non-daemon threads get deleted (join all -non-daemon threads), rather than just wait until non-daemon Python threads -complete. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst deleted file mode 100644 index 295ddebb2a40..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` -attribute fails to better mimick :class:`_io.IOBase` finalizer. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst deleted file mode 100644 index 337c8e2668c4..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if -internal tasks weak set is changed by another thread during iteration. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst deleted file mode 100644 index 6dd49998cb4c..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst +++ /dev/null @@ -1 +0,0 @@ -Change the format of feature_version to be a (major, minor) tuple. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst deleted file mode 100644 index 5271a495624d..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :meth:`RobotFileParser.crawl_delay` and -:meth:`RobotFileParser.request_rate` to return ``None`` rather than -raise :exc:`AttributeError` when no relevant rule is defined in the -robots.txt file. Patch by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rs= t b/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst deleted file mode 100644 index 58fc66b59059..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst +++ /dev/null @@ -1 +0,0 @@ -Allow pure Python implementation of :mod:`pickle` to work even when the C :m= od:`_pickle` module is unavailable. diff --git a/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst deleted file mode 100644 index efd1f55c0135..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters -on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst deleted file mode 100644 index d740b9b62b08..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix asyncio sendfile support when sendfile sends extra data in fallback -mode. diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst deleted file mode 100644 index 7cdc56a72ce4..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst +++ /dev/null @@ -1 +0,0 @@ -Use threadpool for reading from file for sendfile fallback mode. diff --git a/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rs= t b/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst deleted file mode 100644 index ded1570b308f..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Email with single part but content-type set to ``multipart/*`` doesn't raise -AttributeError anymore. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst deleted file mode 100644 index 8d0d2fa311bc..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that was causing the :mod:`queue` module to fail if the -accelerator module was not available. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst deleted file mode 100644 index f6829fb1727e..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst +++ /dev/null @@ -1,4 +0,0 @@ -The *dist* argument for statistics.quantiles() is now positional only. The -current name doesn't reflect that the argument can be either a dataset or a -distribution. Marking the parameter as positional avoids confusion and -makes it possible to change the name later. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst deleted file mode 100644 index b8fac4673686..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix IndexError in parsing a header value ending unexpectedly. Patch by Abhil= ash -Raj. diff --git a/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rs= t b/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst deleted file mode 100644 index 3ce4102129f0..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, -rather than the ANSI code page: see :pep:`529` for the rationale. The functi= on -is no longer deprecated on Windows. diff --git a/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rs= t b/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst deleted file mode 100644 index dea1a2925014..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`os.sched_setaffinity` now correctly handles errors that arise during = iteration over its ``mask`` argument. -Patch by Brandt Bucher. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rs= t b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst deleted file mode 100644 index 2cdce6b24dc6..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst +++ /dev/null @@ -1,4 +0,0 @@ -SSLContext.post_handshake_auth =3D 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/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rs= t b/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst deleted file mode 100644 index 80719ee152d7..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst +++ /dev/null @@ -1 +0,0 @@ -Update vendorized expat version to 2.2.7. diff --git a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rs= t b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst deleted file mode 100644 index b336e061e15e..000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst +++ /dev/null @@ -1,2 +0,0 @@ -http.client now enables TLS 1.3 post-handshake authentication for default -context or if a cert_file is passed to HTTPSConnection. diff --git a/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.r= st b/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst deleted file mode 100644 index 90aa30192fc8..000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst +++ /dev/null @@ -1 +0,0 @@ -Updated OpenSSL to 1.1.1c in Windows installer diff --git a/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.r= st b/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst deleted file mode 100644 index 7506fa9064b1..000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`io.open_code` is now used when reading :file:`.pth` files. diff --git a/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.r= st b/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst deleted file mode 100644 index 1b724ff559e2..000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst +++ /dev/null @@ -1,5 +0,0 @@ -Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, -:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, -:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, -:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, -:func:`os.scandir` and :func:`breakpoint`. diff --git a/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.r= st b/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst deleted file mode 100644 index 4f4a62e78374..000000000000 --- a/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst +++ /dev/null @@ -1,4 +0,0 @@ -ssl.match_hostname() no longer accepts IPv4 addresses with additional text -after the address and only quad-dotted notation without trailing -whitespaces. Some inet_aton() implementations ignore whitespace and all data -after whitespace, e.g. '127.0.0.1 whatever'. diff --git a/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.r= st b/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst deleted file mode 100644 index a8bde90db496..000000000000 --- a/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adds audit events for the range of supported run commands (see -:ref:`using-on-general`). diff --git a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst = b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst deleted file mode 100644 index 233640716d15..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Modify the test_uuid logic to test when a program is available -AND can be used to obtain a MACADDR as basis for an UUID. -Patch by M. Felt diff --git a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst = b/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst deleted file mode 100644 index 138a22f6acc2..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst +++ /dev/null @@ -1,2 +0,0 @@ -``test_venv.test_mutiprocessing()`` now explicitly calls -``pool.terminate()`` to wait until the pool completes. diff --git a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst = b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst deleted file mode 100644 index f2f0a8b8d8ea..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst +++ /dev/null @@ -1 +0,0 @@ -Rewrite ``_PyObject_IsFreed()`` unit tests. diff --git a/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst = b/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst deleted file mode 100644 index 27ce78a70f2b..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method -now ignores unraisable exception raised when clearing its ``unraisable`` -attribute. diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst = b/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst deleted file mode 100644 index 3d3011b51c5b..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a -running thread and leaking a reference. diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst = b/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst deleted file mode 100644 index 23b6d00f42c5..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid TimeoutError in test_asyncio: test_start_tls_server_1() diff --git a/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst = b/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst deleted file mode 100644 index 43fdc1030c57..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_gdb no longer fails if it gets an "unexpected" message on stderr: it now -ignores stderr. The purpose of test_gdb is to test that python-gdb.py comman= ds -work as expected, not to test gdb. diff --git a/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst = b/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst deleted file mode 100644 index 3d5350de4f43..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add --cleanup option to python3 -m test to remove ``test_python_*`` -directories of previous failed jobs. Add "make cleantest" to run -``python3 -m test --cleanup``. - diff --git a/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst = b/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst deleted file mode 100644 index 737c78189009..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() -to get groups. Rename also the test to test_chown_gid(). diff --git a/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst = b/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst deleted file mode 100644 index 20e52d3c74f7..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_wsgiref.testEnviron() to no longer depend on the environment -variables (don't fail if "X" variable is set). diff --git a/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst = b/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst deleted file mode 100644 index 9f4033831d68..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_shutil to no longer leak temporary files. diff --git a/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst = b/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst deleted file mode 100644 index cb884d926590..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst +++ /dev/null @@ -1 +0,0 @@ -Remove no longer necessary code from c locale coercion tests diff --git a/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst = b/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst deleted file mode 100644 index b05209159cc8..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test failures when IPv6 is unavailable or disabled. diff --git a/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst = b/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst deleted file mode 100644 index c379b504ba8a..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst +++ /dev/null @@ -1,2 +0,0 @@ -multiprocessing tests now explicitly call ``_run_finalizers()`` to -immediately remove temporary directories created by tests. diff --git a/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst = b/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst deleted file mode 100644 index 6671ffe922fd..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_winconsoleio doesn't leak a temporary file anymore: use -tempfile.TemporaryFile() to remove it when the test completes. diff --git a/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst = b/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst deleted file mode 100644 index 215a0a144459..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_concurrent_futures now cleans up multiprocessing to remove immediately -temporary directories created by multiprocessing.util.get_temp_dir(). diff --git a/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst = b/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst deleted file mode 100644 index 8610509e4b72..000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_distutils.test_build_ext() is now able to remove the temporary -directory on Windows: don't import the newly built C extension ("xx") in the -current process, but test it in a separated process. diff --git a/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rs= t b/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst deleted file mode 100644 index 618cfcae7b89..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure ``time.tzname`` is correct on Windows when the active code page is -set to CP_UTF7 or CP_UTF8. diff --git a/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rs= t b/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst deleted file mode 100644 index a4dcfcde35b0..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, :func:`os.dup` no longer creates an inheritable fd when handling -a character file. diff --git a/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rs= t b/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst deleted file mode 100644 index 8fea56a00fdc..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows builds to use SQLite 3.28.0. diff --git a/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rs= t b/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst deleted file mode 100644 index df2efd4a9a41..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst +++ /dev/null @@ -1 +0,0 @@ -Removes libpython38.a from standard Windows distribution. diff --git a/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rs= t b/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst deleted file mode 100644 index 5eaed61a9261..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes path for :data:`sys.executable` when running from the Microsoft Store. diff --git a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rs= t b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst deleted file mode 100644 index d39576545efa..000000000000 --- a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Officially drop support for creating bdist_wininst installers on non-Windows -systems. diff --git a/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst = b/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst deleted file mode 100644 index 164950a37c83..000000000000 --- a/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst +++ /dev/null @@ -1 +0,0 @@ -Updated OpenSSL to 1.1.1c in macOS installer. diff --git a/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst = b/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst deleted file mode 100644 index 5e05ac56b095..000000000000 --- a/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use SQLite 3.28.0. diff --git a/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst = b/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst deleted file mode 100644 index c50ac638df57..000000000000 --- a/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst +++ /dev/null @@ -1,4 +0,0 @@ -Avoid test suite failures on macOS by no longer calling resource.setrlimit -to increase the process stack size limit at runtime. The runtime change is -no longer needed since the interpreter is being built with a larger default -stack size. diff --git a/README.rst b/README.rst index b0a0ce7ec287..e1d89b3d811a 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.8.0 beta 1 +This is Python version 3.8.0 beta 2 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 .. image:: https://travis-ci.org/python/cpython.svg?branch=3Dmaster From webhook-mailer at python.org Fri Jul 12 17:22:26 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 12 Jul 2019 21:22:26 -0000 Subject: [Python-checkins] bpo-19696: Move threaded_import_hangers (GH-14655) Message-ID: https://github.com/python/cpython/commit/a65c977552507dd19d2cc073fc91ae22cc66bbff commit: a65c977552507dd19d2cc073fc91ae22cc66bbff branch: master author: Kyle Stanley committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-12T14:22:05-07:00 summary: bpo-19696: Move threaded_import_hangers (GH-14655) Move `threaded_import_hangers`, a dependency of `test_threaded_import`, to the directory `test_importlib/`. Also update the import references for `threaded_import_hangers` in `test_threaded_import`. https://bugs.python.org/issue19696 files: A Lib/test/test_importlib/threaded_import_hangers.py D Lib/test/threaded_import_hangers.py M Lib/test/test_importlib/test_threaded_import.py diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index 8607f363db21..d1f64c70fac8 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -178,11 +178,11 @@ def test_import_hangers(self): # In case this test is run again, make sure the helper module # gets loaded from scratch again. try: - del sys.modules['test.threaded_import_hangers'] + del sys.modules['test.test_importlib.threaded_import_hangers'] except KeyError: pass - import test.threaded_import_hangers - self.assertFalse(test.threaded_import_hangers.errors) + import test.test_importlib.threaded_import_hangers + self.assertFalse(test.test_importlib.threaded_import_hangers.errors) def test_circular_imports(self): # The goal of this test is to exercise implementations of the import diff --git a/Lib/test/threaded_import_hangers.py b/Lib/test/test_importlib/threaded_import_hangers.py similarity index 100% rename from Lib/test/threaded_import_hangers.py rename to Lib/test/test_importlib/threaded_import_hangers.py From webhook-mailer at python.org Fri Jul 12 18:35:43 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 12 Jul 2019 22:35:43 -0000 Subject: [Python-checkins] bpo-37521: No longer treat insertion into sys.modules as optional in importlib examples (GH-14723) Message-ID: https://github.com/python/cpython/commit/0827064c955f88df8ba5621d8e3d81be3cfc26a9 commit: 0827064c955f88df8ba5621d8e3d81be3cfc26a9 branch: master author: Brett Cannon <54418+brettcannon at users.noreply.github.com> committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-07-12T15:35:34-07:00 summary: bpo-37521: No longer treat insertion into sys.modules as optional in importlib examples (GH-14723) Fix importlib examples to insert any newly created modules via importlib.util.module_from_spec() immediately into sys.modules instead of after calling loader.exec_module(). Thanks to Benjamin Mintz for finding the bug. https://bugs.python.org/issue37521 files: A Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst M Doc/library/importlib.rst diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index df184b33d0e7..9fab0779aa74 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1638,15 +1638,16 @@ import, then you should use :func:`importlib.util.find_spec`. # For illustrative purposes. name = 'itertools' - spec = importlib.util.find_spec(name) - if spec is None: - print("can't find the itertools module") + if name in sys.modules: + print(f"{name!r} already in sys.modules") + elif (spec := importlib.util.find_spec(name)) is None: + print(f"can't find the {name!r} module") else: # If you chose to perform the actual import ... module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - # Adding the module to sys.modules is optional. sys.modules[name] = module + spec.loader.exec_module(module) + print(f"{name!r} has been imported") Importing a source file directly @@ -1665,10 +1666,9 @@ To import a Python source file directly, use the following recipe spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - # Optional; only necessary if you want to be able to import the module - # by name later. sys.modules[module_name] = module + spec.loader.exec_module(module) + Setting up an importer @@ -1740,8 +1740,8 @@ Python 3.6 and newer for other parts of the code). msg = f'No module named {absolute_name!r}' raise ModuleNotFoundError(msg, name=absolute_name) module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) sys.modules[absolute_name] = module + spec.loader.exec_module(module) if path is not None: setattr(parent_module, child_name, module) return module diff --git a/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst new file mode 100644 index 000000000000..35d7f56f732f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst @@ -0,0 +1,5 @@ +Fix `importlib` examples to insert any newly created modules via +importlib.util.module_from_spec() immediately into sys.modules instead of +after calling loader.exec_module(). + +Thanks to Benjamin Mintz for finding the bug. From webhook-mailer at python.org Fri Jul 12 18:51:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 12 Jul 2019 22:51:52 -0000 Subject: [Python-checkins] [3.8] bpo-37521: No longer treat insertion into sys.modules as optional in importlib examples (GH-14723) (GH-14724) Message-ID: https://github.com/python/cpython/commit/bfb709b771230e7e466961b5ddf4852962602450 commit: bfb709b771230e7e466961b5ddf4852962602450 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-12T15:51:48-07:00 summary: [3.8] bpo-37521: No longer treat insertion into sys.modules as optional in importlib examples (GH-14723) (GH-14724) Fix importlib examples to insert any newly created modules via importlib.util.module_from_spec() immediately into sys.modules instead of after calling loader.exec_module(). Thanks to Benjamin Mintz for finding the bug. https://bugs.python.org/issue37521 (cherry picked from commit 0827064c955f88df8ba5621d8e3d81be3cfc26a9) Co-authored-by: Brett Cannon <54418+brettcannon at users.noreply.github.com> https://bugs.python.org/issue37521 files: A Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst M Doc/library/importlib.rst diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index df184b33d0e7..9fab0779aa74 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1638,15 +1638,16 @@ import, then you should use :func:`importlib.util.find_spec`. # For illustrative purposes. name = 'itertools' - spec = importlib.util.find_spec(name) - if spec is None: - print("can't find the itertools module") + if name in sys.modules: + print(f"{name!r} already in sys.modules") + elif (spec := importlib.util.find_spec(name)) is None: + print(f"can't find the {name!r} module") else: # If you chose to perform the actual import ... module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - # Adding the module to sys.modules is optional. sys.modules[name] = module + spec.loader.exec_module(module) + print(f"{name!r} has been imported") Importing a source file directly @@ -1665,10 +1666,9 @@ To import a Python source file directly, use the following recipe spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - # Optional; only necessary if you want to be able to import the module - # by name later. sys.modules[module_name] = module + spec.loader.exec_module(module) + Setting up an importer @@ -1740,8 +1740,8 @@ Python 3.6 and newer for other parts of the code). msg = f'No module named {absolute_name!r}' raise ModuleNotFoundError(msg, name=absolute_name) module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) sys.modules[absolute_name] = module + spec.loader.exec_module(module) if path is not None: setattr(parent_module, child_name, module) return module diff --git a/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst new file mode 100644 index 000000000000..35d7f56f732f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst @@ -0,0 +1,5 @@ +Fix `importlib` examples to insert any newly created modules via +importlib.util.module_from_spec() immediately into sys.modules instead of +after calling loader.exec_module(). + +Thanks to Benjamin Mintz for finding the bug. From webhook-mailer at python.org Fri Jul 12 23:16:13 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Sat, 13 Jul 2019 03:16:13 -0000 Subject: [Python-checkins] closes bpo-37347: Fix refcount problem in sqlite3. (GH-14268) Message-ID: https://github.com/python/cpython/commit/b9a0376b0dedf16a2f82fa43d851119d1f7a2707 commit: b9a0376b0dedf16a2f82fa43d851119d1f7a2707 branch: master author: gescheit committer: Benjamin Peterson date: 2019-07-12T20:15:48-07:00 summary: closes bpo-37347: Fix refcount problem in sqlite3. (GH-14268) files: A Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst M Lib/sqlite3/test/regression.py M Misc/ACKS M Modules/_sqlite/connection.c M Modules/_sqlite/connection.h M setup.py diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index ee326168bc12..c714116ac492 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -25,6 +25,7 @@ import unittest import sqlite3 as sqlite import weakref +import functools from test import support class RegressionTests(unittest.TestCase): @@ -383,72 +384,26 @@ def CheckDelIsolation_levelSegfault(self): with self.assertRaises(AttributeError): del self.con.isolation_level + def CheckBpo37347(self): + class Printer: + def log(self, *args): + return sqlite.SQLITE_OK -class UnhashableFunc: - __hash__ = None + for method in [self.con.set_trace_callback, + functools.partial(self.con.set_progress_handler, n=1), + self.con.set_authorizer]: + printer_instance = Printer() + method(printer_instance.log) + method(printer_instance.log) + self.con.execute("select 1") # trigger seg fault + method(None) - def __init__(self, return_value=None): - self.calls = 0 - self.return_value = return_value - - def __call__(self, *args, **kwargs): - self.calls += 1 - return self.return_value - - -class UnhashableCallbacksTestCase(unittest.TestCase): - """ - https://bugs.python.org/issue34052 - - Registering unhashable callbacks raises TypeError, callbacks are not - registered in SQLite after such registration attempt. - """ - def setUp(self): - self.con = sqlite.connect(':memory:') - - def tearDown(self): - self.con.close() - - def test_progress_handler(self): - f = UnhashableFunc(return_value=0) - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.set_progress_handler(f, 1) - self.con.execute('SELECT 1') - self.assertFalse(f.calls) - - def test_func(self): - func_name = 'func_name' - f = UnhashableFunc() - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.create_function(func_name, 0, f) - msg = 'no such function: %s' % func_name - with self.assertRaisesRegex(sqlite.OperationalError, msg): - self.con.execute('SELECT %s()' % func_name) - self.assertFalse(f.calls) - - def test_authorizer(self): - f = UnhashableFunc(return_value=sqlite.SQLITE_DENY) - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.set_authorizer(f) - self.con.execute('SELECT 1') - self.assertFalse(f.calls) - - def test_aggr(self): - class UnhashableType(type): - __hash__ = None - aggr_name = 'aggr_name' - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.create_aggregate(aggr_name, 0, UnhashableType('Aggr', (), {})) - msg = 'no such function: %s' % aggr_name - with self.assertRaisesRegex(sqlite.OperationalError, msg): - self.con.execute('SELECT %s()' % aggr_name) def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") return unittest.TestSuite(( regression_suite, - unittest.makeSuite(UnhashableCallbacksTestCase), )) def test(): diff --git a/Misc/ACKS b/Misc/ACKS index d916c45a8e44..c0119992cffe 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1870,3 +1870,4 @@ Diego Rojas Edison Abahurire Geoff Shannon Batuhan Taskaya +Aleksandr Balezin diff --git a/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst b/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst new file mode 100644 index 000000000000..1e61f5e0b3db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst @@ -0,0 +1,6 @@ +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` +:meth:`sqlite3.Connection.set_trace_callback` +methods lead to segfaults if some of these methods are called twice with an equal object but not the same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. \ No newline at end of file diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 47b8b62cea26..ae03aed8f0b8 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -186,10 +186,9 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } self->check_same_thread = check_same_thread; - Py_XSETREF(self->function_pinboard, PyDict_New()); - if (!self->function_pinboard) { - return -1; - } + self->function_pinboard_trace_callback = NULL; + self->function_pinboard_progress_handler = NULL; + self->function_pinboard_authorizer_cb = NULL; Py_XSETREF(self->collations, PyDict_New()); if (!self->collations) { @@ -249,19 +248,18 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) /* Clean up if user has not called .close() explicitly. */ if (self->db) { - Py_BEGIN_ALLOW_THREADS SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS } Py_XDECREF(self->isolation_level); - Py_XDECREF(self->function_pinboard); + Py_XDECREF(self->function_pinboard_trace_callback); + Py_XDECREF(self->function_pinboard_progress_handler); + Py_XDECREF(self->function_pinboard_authorizer_cb); Py_XDECREF(self->row_factory); Py_XDECREF(self->text_factory); Py_XDECREF(self->collations); Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); } @@ -342,9 +340,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - Py_BEGIN_ALLOW_THREADS rc = SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -808,6 +804,11 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) Py_SETREF(self->cursors, new_list); } +static void _destructor(void* args) +{ + Py_DECREF((PyObject*)args); +} + PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; @@ -843,17 +844,16 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec flags |= SQLITE_DETERMINISTIC; #endif } - if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, - name, - narg, - flags, - (void*)func, - _pysqlite_func_callback, - NULL, - NULL); + Py_INCREF(func); + rc = sqlite3_create_function_v2(self->db, + name, + narg, + flags, + (void*)func, + _pysqlite_func_callback, + NULL, + NULL, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ @@ -880,11 +880,16 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje kwlist, &name, &n_arg, &aggregate_class)) { return NULL; } - - if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_pysqlite_step_callback, &_pysqlite_final_callback); + Py_INCREF(aggregate_class); + rc = sqlite3_create_function_v2(self->db, + name, + n_arg, + SQLITE_UTF8, + (void*)aggregate_class, + 0, + &_pysqlite_step_callback, + &_pysqlite_final_callback, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); @@ -1003,13 +1008,14 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P return NULL; } - if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1) { - return NULL; - } rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); + Py_XSETREF(self->function_pinboard_authorizer_cb, NULL); return NULL; + } else { + Py_INCREF(authorizer_cb); + Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb); } Py_RETURN_NONE; } @@ -1033,12 +1039,12 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s if (progress_handler == Py_None) { /* None clears the progress handler previously set */ sqlite3_progress_handler(self->db, 0, 0, (void*)0); + Py_XSETREF(self->function_pinboard_progress_handler, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1) - return NULL; sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); + Py_INCREF(progress_handler); + Py_XSETREF(self->function_pinboard_progress_handler, progress_handler); } - Py_RETURN_NONE; } @@ -1060,10 +1066,11 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel if (trace_callback == Py_None) { /* None clears the trace callback previously set */ sqlite3_trace(self->db, 0, (void*)0); + Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, trace_callback, Py_None) == -1) - return NULL; sqlite3_trace(self->db, _trace_callback, trace_callback); + Py_INCREF(trace_callback); + Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } Py_RETURN_NONE; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 4e9d94c5f308..206085e00a00 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -85,11 +85,10 @@ typedef struct */ PyObject* text_factory; - /* remember references to functions/classes used in - * create_function/create/aggregate, use these as dictionary keys, so we - * can keep the total system refcount constant by clearing that dictionary - * in connection_dealloc */ - PyObject* function_pinboard; + /* remember references to object used in trace_callback/progress_handler/authorizer_cb */ + PyObject* function_pinboard_trace_callback; + PyObject* function_pinboard_progress_handler; + PyObject* function_pinboard_authorizer_cb; /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; diff --git a/setup.py b/setup.py index 3ec89cedfd57..7cd77257ae35 100644 --- a/setup.py +++ b/setup.py @@ -1357,7 +1357,7 @@ def detect_sqlite(self): ] if CROSS_COMPILING: sqlite_inc_paths = [] - MIN_SQLITE_VERSION_NUMBER = (3, 3, 9) + MIN_SQLITE_VERSION_NUMBER = (3, 7, 2) MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER]) From webhook-mailer at python.org Fri Jul 12 23:33:58 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 13 Jul 2019 03:33:58 -0000 Subject: [Python-checkins] closes bpo-37347: Fix refcount problem in sqlite3. (GH-14268) Message-ID: https://github.com/python/cpython/commit/36101c2c5daf692d1716e17720c6c5197f28e25d commit: 36101c2c5daf692d1716e17720c6c5197f28e25d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-07-12T20:33:53-07:00 summary: closes bpo-37347: Fix refcount problem in sqlite3. (GH-14268) (cherry picked from commit b9a0376b0dedf16a2f82fa43d851119d1f7a2707) Co-authored-by: gescheit files: A Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst M Lib/sqlite3/test/regression.py M Misc/ACKS M Modules/_sqlite/connection.c M Modules/_sqlite/connection.h M setup.py diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 865bd88f74f1..dd5aec50d186 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -25,6 +25,7 @@ import unittest import sqlite3 as sqlite import weakref +import functools from test import support class RegressionTests(unittest.TestCase): @@ -383,72 +384,26 @@ def CheckDelIsolation_levelSegfault(self): with self.assertRaises(AttributeError): del self.con.isolation_level + def CheckBpo37347(self): + class Printer: + def log(self, *args): + return sqlite.SQLITE_OK -class UnhashableFunc: - __hash__ = None + for method in [self.con.set_trace_callback, + functools.partial(self.con.set_progress_handler, n=1), + self.con.set_authorizer]: + printer_instance = Printer() + method(printer_instance.log) + method(printer_instance.log) + self.con.execute("select 1") # trigger seg fault + method(None) - def __init__(self, return_value=None): - self.calls = 0 - self.return_value = return_value - - def __call__(self, *args, **kwargs): - self.calls += 1 - return self.return_value - - -class UnhashableCallbacksTestCase(unittest.TestCase): - """ - https://bugs.python.org/issue34052 - - Registering unhashable callbacks raises TypeError, callbacks are not - registered in SQLite after such registration attempt. - """ - def setUp(self): - self.con = sqlite.connect(':memory:') - - def tearDown(self): - self.con.close() - - def test_progress_handler(self): - f = UnhashableFunc(return_value=0) - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.set_progress_handler(f, 1) - self.con.execute('SELECT 1') - self.assertFalse(f.calls) - - def test_func(self): - func_name = 'func_name' - f = UnhashableFunc() - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.create_function(func_name, 0, f) - msg = 'no such function: %s' % func_name - with self.assertRaisesRegex(sqlite.OperationalError, msg): - self.con.execute('SELECT %s()' % func_name) - self.assertFalse(f.calls) - - def test_authorizer(self): - f = UnhashableFunc(return_value=sqlite.SQLITE_DENY) - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.set_authorizer(f) - self.con.execute('SELECT 1') - self.assertFalse(f.calls) - - def test_aggr(self): - class UnhashableType(type): - __hash__ = None - aggr_name = 'aggr_name' - with self.assertRaisesRegex(TypeError, 'unhashable type'): - self.con.create_aggregate(aggr_name, 0, UnhashableType('Aggr', (), {})) - msg = 'no such function: %s' % aggr_name - with self.assertRaisesRegex(sqlite.OperationalError, msg): - self.con.execute('SELECT %s()' % aggr_name) def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") return unittest.TestSuite(( regression_suite, - unittest.makeSuite(UnhashableCallbacksTestCase), )) def test(): diff --git a/Misc/ACKS b/Misc/ACKS index f427d8b5a929..53285403e695 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1866,3 +1866,4 @@ Diego Rojas Edison Abahurire Geoff Shannon Batuhan Taskaya +Aleksandr Balezin diff --git a/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst b/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst new file mode 100644 index 000000000000..1e61f5e0b3db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst @@ -0,0 +1,6 @@ +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` +:meth:`sqlite3.Connection.set_trace_callback` +methods lead to segfaults if some of these methods are called twice with an equal object but not the same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. \ No newline at end of file diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0d6462ef7dc2..ebe073f644aa 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -186,10 +186,9 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } self->check_same_thread = check_same_thread; - Py_XSETREF(self->function_pinboard, PyDict_New()); - if (!self->function_pinboard) { - return -1; - } + self->function_pinboard_trace_callback = NULL; + self->function_pinboard_progress_handler = NULL; + self->function_pinboard_authorizer_cb = NULL; Py_XSETREF(self->collations, PyDict_New()); if (!self->collations) { @@ -249,19 +248,18 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) /* Clean up if user has not called .close() explicitly. */ if (self->db) { - Py_BEGIN_ALLOW_THREADS SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS } Py_XDECREF(self->isolation_level); - Py_XDECREF(self->function_pinboard); + Py_XDECREF(self->function_pinboard_trace_callback); + Py_XDECREF(self->function_pinboard_progress_handler); + Py_XDECREF(self->function_pinboard_authorizer_cb); Py_XDECREF(self->row_factory); Py_XDECREF(self->text_factory); Py_XDECREF(self->collations); Py_XDECREF(self->statements); Py_XDECREF(self->cursors); - Py_TYPE(self)->tp_free((PyObject*)self); } @@ -342,9 +340,7 @@ PyObject* pysqlite_connection_close(pysqlite_Connection* self, PyObject* args) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - Py_BEGIN_ALLOW_THREADS rc = SQLITE3_CLOSE(self->db); - Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -808,6 +804,11 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self) Py_SETREF(self->cursors, new_list); } +static void _destructor(void* args) +{ + Py_DECREF((PyObject*)args); +} + PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) { static char *kwlist[] = {"name", "narg", "func", "deterministic", NULL}; @@ -843,17 +844,16 @@ PyObject* pysqlite_connection_create_function(pysqlite_Connection* self, PyObjec flags |= SQLITE_DETERMINISTIC; #endif } - if (PyDict_SetItem(self->function_pinboard, func, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, - name, - narg, - flags, - (void*)func, - _pysqlite_func_callback, - NULL, - NULL); + Py_INCREF(func); + rc = sqlite3_create_function_v2(self->db, + name, + narg, + flags, + (void*)func, + _pysqlite_func_callback, + NULL, + NULL, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ @@ -880,11 +880,16 @@ PyObject* pysqlite_connection_create_aggregate(pysqlite_Connection* self, PyObje kwlist, &name, &n_arg, &aggregate_class)) { return NULL; } - - if (PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None) == -1) { - return NULL; - } - rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_pysqlite_step_callback, &_pysqlite_final_callback); + Py_INCREF(aggregate_class); + rc = sqlite3_create_function_v2(self->db, + name, + n_arg, + SQLITE_UTF8, + (void*)aggregate_class, + 0, + &_pysqlite_step_callback, + &_pysqlite_final_callback, + &_destructor); // will decref func if (rc != SQLITE_OK) { /* Workaround for SQLite bug: no error code or string is available here */ PyErr_SetString(pysqlite_OperationalError, "Error creating aggregate"); @@ -1003,13 +1008,14 @@ static PyObject* pysqlite_connection_set_authorizer(pysqlite_Connection* self, P return NULL; } - if (PyDict_SetItem(self->function_pinboard, authorizer_cb, Py_None) == -1) { - return NULL; - } rc = sqlite3_set_authorizer(self->db, _authorizer_callback, (void*)authorizer_cb); if (rc != SQLITE_OK) { PyErr_SetString(pysqlite_OperationalError, "Error setting authorizer callback"); + Py_XSETREF(self->function_pinboard_authorizer_cb, NULL); return NULL; + } else { + Py_INCREF(authorizer_cb); + Py_XSETREF(self->function_pinboard_authorizer_cb, authorizer_cb); } Py_RETURN_NONE; } @@ -1033,12 +1039,12 @@ static PyObject* pysqlite_connection_set_progress_handler(pysqlite_Connection* s if (progress_handler == Py_None) { /* None clears the progress handler previously set */ sqlite3_progress_handler(self->db, 0, 0, (void*)0); + Py_XSETREF(self->function_pinboard_progress_handler, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, progress_handler, Py_None) == -1) - return NULL; sqlite3_progress_handler(self->db, n, _progress_handler, progress_handler); + Py_INCREF(progress_handler); + Py_XSETREF(self->function_pinboard_progress_handler, progress_handler); } - Py_RETURN_NONE; } @@ -1060,10 +1066,11 @@ static PyObject* pysqlite_connection_set_trace_callback(pysqlite_Connection* sel if (trace_callback == Py_None) { /* None clears the trace callback previously set */ sqlite3_trace(self->db, 0, (void*)0); + Py_XSETREF(self->function_pinboard_trace_callback, NULL); } else { - if (PyDict_SetItem(self->function_pinboard, trace_callback, Py_None) == -1) - return NULL; sqlite3_trace(self->db, _trace_callback, trace_callback); + Py_INCREF(trace_callback); + Py_XSETREF(self->function_pinboard_trace_callback, trace_callback); } Py_RETURN_NONE; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 4e9d94c5f308..206085e00a00 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -85,11 +85,10 @@ typedef struct */ PyObject* text_factory; - /* remember references to functions/classes used in - * create_function/create/aggregate, use these as dictionary keys, so we - * can keep the total system refcount constant by clearing that dictionary - * in connection_dealloc */ - PyObject* function_pinboard; + /* remember references to object used in trace_callback/progress_handler/authorizer_cb */ + PyObject* function_pinboard_trace_callback; + PyObject* function_pinboard_progress_handler; + PyObject* function_pinboard_authorizer_cb; /* a dictionary of registered collation name => collation callable mappings */ PyObject* collations; diff --git a/setup.py b/setup.py index edc343424297..6cbbec9e1212 100644 --- a/setup.py +++ b/setup.py @@ -1348,7 +1348,7 @@ def detect_sqlite(self): ] if CROSS_COMPILING: sqlite_inc_paths = [] - MIN_SQLITE_VERSION_NUMBER = (3, 3, 9) + MIN_SQLITE_VERSION_NUMBER = (3, 7, 2) MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER]) From webhook-mailer at python.org Sat Jul 13 04:35:16 2019 From: webhook-mailer at python.org (Xiang Zhang) Date: Sat, 13 Jul 2019 08:35:16 -0000 Subject: [Python-checkins] Fix typo in re.escape documentation (GH-14722) Message-ID: https://github.com/python/cpython/commit/fb6c1f8d3b116c7e3e3f814bf750d984a2f2ecbf commit: fb6c1f8d3b116c7e3e3f814bf750d984a2f2ecbf branch: master author: Robert DiPietro committer: Xiang Zhang date: 2019-07-13T16:35:04+08:00 summary: Fix typo in re.escape documentation (GH-14722) files: M D