From webhook-mailer at python.org Mon Jun 1 02:58:21 2020 From: webhook-mailer at python.org (Christian Heimes) Date: Mon, 01 Jun 2020 06:58:21 -0000 Subject: [Python-checkins] bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Message-ID: https://github.com/python/cpython/commit/a871f692b4a2e6c7d45579693e787edc0af1a02c commit: a871f692b4a2e6c7d45579693e787edc0af1a02c branch: master author: Christian Heimes committer: GitHub date: 2020-06-01T08:58:14+02:00 summary: bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Fix :mod:`ssl`` code to be compatible with OpenSSL 1.1.x builds that use ``no-deprecated`` and ``--api=1.1.0``. Note: Tests assume full OpenSSL API and fail with limited API. Signed-off-by: Christian Heimes Co-authored-by: Mark Wright files: A Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst M Modules/_ssl.c M Tools/ssl/multissltests.py diff --git a/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst new file mode 100644 index 0000000000000..c4cfa56ce02c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst @@ -0,0 +1,2 @@ +Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use +``no-deprecated`` and ``--api=1.1.0``. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 5fe65a8a1d6df..5e82fe41a76ec 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -142,6 +142,24 @@ static void _PySSLFixErrno(void) { # define PY_OPENSSL_1_1_API 1 #endif +/* OpenSSL API compat */ +#ifdef OPENSSL_API_COMPAT +#if OPENSSL_API_COMPAT >= 0x10100000L + +/* OpenSSL API 1.1.0+ does not include version methods */ +#ifndef OPENSSL_NO_TLS1_METHOD +#define OPENSSL_NO_TLS1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_1_METHOD +#define OPENSSL_NO_TLS1_1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_2_METHOD +#define OPENSSL_NO_TLS1_2_METHOD 1 +#endif + +#endif /* >= 1.1.0 compcat */ +#endif /* OPENSSL_API_COMPAT */ + /* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL # define PY_OPENSSL_1_1_API 1 @@ -201,6 +219,12 @@ static void _PySSLFixErrno(void) { #define TLS_method SSLv23_method #define TLS_client_method SSLv23_client_method #define TLS_server_method SSLv23_server_method +#define ASN1_STRING_get0_data ASN1_STRING_data +#define X509_get0_notBefore X509_get_notBefore +#define X509_get0_notAfter X509_get_notAfter +#define OpenSSL_version_num SSLeay +#define OpenSSL_version SSLeay_version +#define OPENSSL_VERSION SSLEAY_VERSION static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) { @@ -885,7 +909,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) goto error; } } else { - if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_data(ip), + if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { _setSSLError(NULL, 0, __FILE__, __LINE__); goto error; @@ -1361,7 +1385,7 @@ _get_peer_alt_names (X509 *certificate) { goto fail; } PyTuple_SET_ITEM(t, 0, v); - v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), + v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as), ASN1_STRING_length(as)); if (v == NULL) { Py_DECREF(t); @@ -1657,7 +1681,7 @@ _decode_certificate(X509 *certificate) { ASN1_INTEGER *serialNumber; char buf[2048]; int len, result; - ASN1_TIME *notBefore, *notAfter; + const ASN1_TIME *notBefore, *notAfter; PyObject *pnotBefore, *pnotAfter; retval = PyDict_New(); @@ -1719,7 +1743,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(sn_obj); (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); + notBefore = X509_get0_notBefore(certificate); ASN1_TIME_print(biobuf, notBefore); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -1736,7 +1760,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(pnotBefore); (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); + notAfter = X509_get0_notAfter(certificate); ASN1_TIME_print(biobuf, notAfter); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -3079,17 +3103,23 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) ctx = SSL_CTX_new(SSLv3_method()); break; #endif -#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) +#if (defined(TLS1_VERSION) && \ + !defined(OPENSSL_NO_TLS1) && \ + !defined(OPENSSL_NO_TLS1_METHOD)) case PY_SSL_VERSION_TLS1: ctx = SSL_CTX_new(TLSv1_method()); break; #endif -#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) +#if (defined(TLS1_1_VERSION) && \ + !defined(OPENSSL_NO_TLS1_1) && \ + !defined(OPENSSL_NO_TLS1_1_METHOD)) case PY_SSL_VERSION_TLS1_1: ctx = SSL_CTX_new(TLSv1_1_method()); break; #endif -#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) +#if (defined(TLS1_2_VERSION) && \ + !defined(OPENSSL_NO_TLS1_2) && \ + !defined(OPENSSL_NO_TLS1_2_METHOD)) case PY_SSL_VERSION_TLS1_2: ctx = SSL_CTX_new(TLSv1_2_method()); break; @@ -3207,7 +3237,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) conservative and assume it wasn't fixed until release. We do this check at runtime to avoid problems from the dynamic linker. See #25672 for more on this. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); @@ -5286,7 +5316,11 @@ PySSL_RAND(int len, int pseudo) if (bytes == NULL) return NULL; if (pseudo) { +#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#else ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#endif if (ok == 0 || ok == 1) return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); } @@ -6373,7 +6407,7 @@ PyInit__ssl(void) /* SSLeay() gives us the version of the library linked against, which could be different from the headers version. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); if (r == NULL) return NULL; @@ -6383,7 +6417,7 @@ PyInit__ssl(void) r = Py_BuildValue("IIIII", major, minor, fix, patch, status); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) return NULL; - r = PyUnicode_FromString(SSLeay_version(SSLEAY_VERSION)); + r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) return NULL; diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 12af98d12c45d..3818165a836fb 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -314,6 +314,7 @@ def _build_src(self): "shared", "--debug", "--prefix={}".format(self.install_dir) ] + # cmd.extend(["no-deprecated", "--api=1.1.0"]) env = os.environ.copy() # set rpath env["LD_RUN_PATH"] = self.lib_dir From webhook-mailer at python.org Mon Jun 1 03:12:00 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 07:12:00 -0000 Subject: [Python-checkins] bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Message-ID: https://github.com/python/cpython/commit/296db8cc2fd089d0d2f23b7dddafc029be9f1eb6 commit: 296db8cc2fd089d0d2f23b7dddafc029be9f1eb6 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T00:11:51-07:00 summary: bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Fix :mod:`ssl`` code to be compatible with OpenSSL 1.1.x builds that use ``no-deprecated`` and ``--api=1.1.0``. Note: Tests assume full OpenSSL API and fail with limited API. Signed-off-by: Christian Heimes Co-authored-by: Mark Wright (cherry picked from commit a871f692b4a2e6c7d45579693e787edc0af1a02c) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst M Modules/_ssl.c M Tools/ssl/multissltests.py diff --git a/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst new file mode 100644 index 0000000000000..c4cfa56ce02c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst @@ -0,0 +1,2 @@ +Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use +``no-deprecated`` and ``--api=1.1.0``. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index bc412ac139476..93cc529e796a0 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -144,6 +144,24 @@ static void _PySSLFixErrno(void) { # define PY_OPENSSL_1_1_API 1 #endif +/* OpenSSL API compat */ +#ifdef OPENSSL_API_COMPAT +#if OPENSSL_API_COMPAT >= 0x10100000L + +/* OpenSSL API 1.1.0+ does not include version methods */ +#ifndef OPENSSL_NO_TLS1_METHOD +#define OPENSSL_NO_TLS1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_1_METHOD +#define OPENSSL_NO_TLS1_1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_2_METHOD +#define OPENSSL_NO_TLS1_2_METHOD 1 +#endif + +#endif /* >= 1.1.0 compcat */ +#endif /* OPENSSL_API_COMPAT */ + /* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL # define PY_OPENSSL_1_1_API 1 @@ -199,6 +217,12 @@ static void _PySSLFixErrno(void) { #define TLS_method SSLv23_method #define TLS_client_method SSLv23_client_method #define TLS_server_method SSLv23_server_method +#define ASN1_STRING_get0_data ASN1_STRING_data +#define X509_get0_notBefore X509_get_notBefore +#define X509_get0_notAfter X509_get_notAfter +#define OpenSSL_version_num SSLeay +#define OpenSSL_version SSLeay_version +#define OPENSSL_VERSION SSLEAY_VERSION static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) { @@ -857,7 +881,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) goto error; } } else { - if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_data(ip), + if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { _setSSLError(NULL, 0, __FILE__, __LINE__); goto error; @@ -1330,7 +1354,7 @@ _get_peer_alt_names (X509 *certificate) { goto fail; } PyTuple_SET_ITEM(t, 0, v); - v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), + v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as), ASN1_STRING_length(as)); if (v == NULL) { Py_DECREF(t); @@ -1626,7 +1650,7 @@ _decode_certificate(X509 *certificate) { ASN1_INTEGER *serialNumber; char buf[2048]; int len, result; - ASN1_TIME *notBefore, *notAfter; + const ASN1_TIME *notBefore, *notAfter; PyObject *pnotBefore, *pnotAfter; retval = PyDict_New(); @@ -1688,7 +1712,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(sn_obj); (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); + notBefore = X509_get0_notBefore(certificate); ASN1_TIME_print(biobuf, notBefore); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -1705,7 +1729,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(pnotBefore); (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); + notAfter = X509_get0_notAfter(certificate); ASN1_TIME_print(biobuf, notAfter); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -3023,17 +3047,23 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) ctx = SSL_CTX_new(SSLv3_method()); break; #endif -#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) +#if (defined(TLS1_VERSION) && \ + !defined(OPENSSL_NO_TLS1) && \ + !defined(OPENSSL_NO_TLS1_METHOD)) case PY_SSL_VERSION_TLS1: ctx = SSL_CTX_new(TLSv1_method()); break; #endif -#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) +#if (defined(TLS1_1_VERSION) && \ + !defined(OPENSSL_NO_TLS1_1) && \ + !defined(OPENSSL_NO_TLS1_1_METHOD)) case PY_SSL_VERSION_TLS1_1: ctx = SSL_CTX_new(TLSv1_1_method()); break; #endif -#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) +#if (defined(TLS1_2_VERSION) && \ + !defined(OPENSSL_NO_TLS1_2) && \ + !defined(OPENSSL_NO_TLS1_2_METHOD)) case PY_SSL_VERSION_TLS1_2: ctx = SSL_CTX_new(TLSv1_2_method()); break; @@ -3146,7 +3176,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) conservative and assume it wasn't fixed until release. We do this check at runtime to avoid problems from the dynamic linker. See #25672 for more on this. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); @@ -5156,7 +5186,11 @@ PySSL_RAND(int len, int pseudo) if (bytes == NULL) return NULL; if (pseudo) { +#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#else ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#endif if (ok == 0 || ok == 1) return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); } @@ -6240,7 +6274,7 @@ PyInit__ssl(void) /* SSLeay() gives us the version of the library linked against, which could be different from the headers version. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); if (r == NULL) return NULL; @@ -6250,7 +6284,7 @@ PyInit__ssl(void) r = Py_BuildValue("IIIII", major, minor, fix, patch, status); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) return NULL; - r = PyUnicode_FromString(SSLeay_version(SSLEAY_VERSION)); + r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) return NULL; diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 12af98d12c45d..3818165a836fb 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -314,6 +314,7 @@ def _build_src(self): "shared", "--debug", "--prefix={}".format(self.install_dir) ] + # cmd.extend(["no-deprecated", "--api=1.1.0"]) env = os.environ.copy() # set rpath env["LD_RUN_PATH"] = self.lib_dir From webhook-mailer at python.org Mon Jun 1 03:17:23 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 07:17:23 -0000 Subject: [Python-checkins] bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Message-ID: https://github.com/python/cpython/commit/9c0ff178a5d5d0992c0be21a7f343a495338ad73 commit: 9c0ff178a5d5d0992c0be21a7f343a495338ad73 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T00:17:16-07:00 summary: bpo-30008: Fix OpenSSL no-deprecated compilation (GH-20397) Fix :mod:`ssl`` code to be compatible with OpenSSL 1.1.x builds that use ``no-deprecated`` and ``--api=1.1.0``. Note: Tests assume full OpenSSL API and fail with limited API. Signed-off-by: Christian Heimes Co-authored-by: Mark Wright (cherry picked from commit a871f692b4a2e6c7d45579693e787edc0af1a02c) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst M Modules/_ssl.c M Tools/ssl/multissltests.py diff --git a/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst new file mode 100644 index 0000000000000..c4cfa56ce02c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-25-22-18-38.bpo-30008.CKC3td.rst @@ -0,0 +1,2 @@ +Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use +``no-deprecated`` and ``--api=1.1.0``. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index b0e3c0432f51d..9fbaecb80739f 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -144,6 +144,24 @@ static void _PySSLFixErrno(void) { # define PY_OPENSSL_1_1_API 1 #endif +/* OpenSSL API compat */ +#ifdef OPENSSL_API_COMPAT +#if OPENSSL_API_COMPAT >= 0x10100000L + +/* OpenSSL API 1.1.0+ does not include version methods */ +#ifndef OPENSSL_NO_TLS1_METHOD +#define OPENSSL_NO_TLS1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_1_METHOD +#define OPENSSL_NO_TLS1_1_METHOD 1 +#endif +#ifndef OPENSSL_NO_TLS1_2_METHOD +#define OPENSSL_NO_TLS1_2_METHOD 1 +#endif + +#endif /* >= 1.1.0 compcat */ +#endif /* OPENSSL_API_COMPAT */ + /* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL # define PY_OPENSSL_1_1_API 1 @@ -203,6 +221,12 @@ static void _PySSLFixErrno(void) { #define TLS_method SSLv23_method #define TLS_client_method SSLv23_client_method #define TLS_server_method SSLv23_server_method +#define ASN1_STRING_get0_data ASN1_STRING_data +#define X509_get0_notBefore X509_get_notBefore +#define X509_get0_notAfter X509_get_notAfter +#define OpenSSL_version_num SSLeay +#define OpenSSL_version SSLeay_version +#define OPENSSL_VERSION SSLEAY_VERSION static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) { @@ -887,7 +911,7 @@ _ssl_configure_hostname(PySSLSocket *self, const char* server_hostname) goto error; } } else { - if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_data(ip), + if (!X509_VERIFY_PARAM_set1_ip(param, ASN1_STRING_get0_data(ip), ASN1_STRING_length(ip))) { _setSSLError(NULL, 0, __FILE__, __LINE__); goto error; @@ -1363,7 +1387,7 @@ _get_peer_alt_names (X509 *certificate) { goto fail; } PyTuple_SET_ITEM(t, 0, v); - v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), + v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as), ASN1_STRING_length(as)); if (v == NULL) { Py_DECREF(t); @@ -1659,7 +1683,7 @@ _decode_certificate(X509 *certificate) { ASN1_INTEGER *serialNumber; char buf[2048]; int len, result; - ASN1_TIME *notBefore, *notAfter; + const ASN1_TIME *notBefore, *notAfter; PyObject *pnotBefore, *pnotAfter; retval = PyDict_New(); @@ -1721,7 +1745,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(sn_obj); (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); + notBefore = X509_get0_notBefore(certificate); ASN1_TIME_print(biobuf, notBefore); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -1738,7 +1762,7 @@ _decode_certificate(X509 *certificate) { Py_DECREF(pnotBefore); (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); + notAfter = X509_get0_notAfter(certificate); ASN1_TIME_print(biobuf, notAfter); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -3081,17 +3105,23 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) ctx = SSL_CTX_new(SSLv3_method()); break; #endif -#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1) +#if (defined(TLS1_VERSION) && \ + !defined(OPENSSL_NO_TLS1) && \ + !defined(OPENSSL_NO_TLS1_METHOD)) case PY_SSL_VERSION_TLS1: ctx = SSL_CTX_new(TLSv1_method()); break; #endif -#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1) +#if (defined(TLS1_1_VERSION) && \ + !defined(OPENSSL_NO_TLS1_1) && \ + !defined(OPENSSL_NO_TLS1_1_METHOD)) case PY_SSL_VERSION_TLS1_1: ctx = SSL_CTX_new(TLSv1_1_method()); break; #endif -#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2) +#if (defined(TLS1_2_VERSION) && \ + !defined(OPENSSL_NO_TLS1_2) && \ + !defined(OPENSSL_NO_TLS1_2_METHOD)) case PY_SSL_VERSION_TLS1_2: ctx = SSL_CTX_new(TLSv1_2_method()); break; @@ -3209,7 +3239,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) conservative and assume it wasn't fixed until release. We do this check at runtime to avoid problems from the dynamic linker. See #25672 for more on this. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); @@ -5289,7 +5319,11 @@ PySSL_RAND(int len, int pseudo) if (bytes == NULL) return NULL; if (pseudo) { +#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#else ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#endif if (ok == 0 || ok == 1) return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); } @@ -6376,7 +6410,7 @@ PyInit__ssl(void) /* SSLeay() gives us the version of the library linked against, which could be different from the headers version. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); if (r == NULL) return NULL; @@ -6386,7 +6420,7 @@ PyInit__ssl(void) r = Py_BuildValue("IIIII", major, minor, fix, patch, status); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) return NULL; - r = PyUnicode_FromString(SSLeay_version(SSLEAY_VERSION)); + r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) return NULL; diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 12af98d12c45d..3818165a836fb 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -314,6 +314,7 @@ def _build_src(self): "shared", "--debug", "--prefix={}".format(self.install_dir) ] + # cmd.extend(["no-deprecated", "--api=1.1.0"]) env = os.environ.copy() # set rpath env["LD_RUN_PATH"] = self.lib_dir From webhook-mailer at python.org Mon Jun 1 05:42:59 2020 From: webhook-mailer at python.org (Mark Shannon) Date: Mon, 01 Jun 2020 09:42:59 -0000 Subject: [Python-checkins] Make sure that keyword arguments are merged into the arguments dictionary when dict unpacking and keyword arguments are interleaved. (GH-20553) Message-ID: https://github.com/python/cpython/commit/db64f12e4deda2abbafb6d2bd5c06762fca991ff commit: db64f12e4deda2abbafb6d2bd5c06762fca991ff branch: master author: Mark Shannon committer: GitHub date: 2020-06-01T10:42:42+01:00 summary: Make sure that keyword arguments are merged into the arguments dictionary when dict unpacking and keyword arguments are interleaved. (GH-20553) files: M Lib/test/test_extcall.py M Python/compile.c diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 1faf29e01d3ca..4205ca82222f2 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -79,6 +79,24 @@ >>> f(1, 2, 3, *(4, 5), x=6, y=7, **UserDict(a=8, b=9)) (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7} +Mix keyword arguments and dict unpacking + + >>> d1 = {'a':1} + + >>> d2 = {'c':3} + + >>> f(b=2, **d1, **d2) + () {'a': 1, 'b': 2, 'c': 3} + + >>> f(**d1, b=2, **d2) + () {'a': 1, 'b': 2, 'c': 3} + + >>> f(**d1, **d2, b=2) + () {'a': 1, 'b': 2, 'c': 3} + + >>> f(**d1, b=2, **d2, d=4) + () {'a': 1, 'b': 2, 'c': 3, 'd': 4} + Examples with invalid arguments (TypeErrors). We're also testing the function names in the exception messages. diff --git a/Python/compile.c b/Python/compile.c index 4a587c00fd402..fccc688affca6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4321,6 +4321,9 @@ compiler_call_helper(struct compiler *c, if (!compiler_subkwargs(c, keywords, i - nseen, i)) { return 0; } + if (have_dict) { + ADDOP_I(c, DICT_MERGE, 1); + } have_dict = 1; nseen = 0; } From webhook-mailer at python.org Mon Jun 1 10:02:48 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 01 Jun 2020 14:02:48 -0000 Subject: [Python-checkins] bpo-40826: Add _Py_EnsureTstateNotNULL() macro (GH-20571) Message-ID: https://github.com/python/cpython/commit/3026cad59b87751a9215111776cac8e819458fce commit: 3026cad59b87751a9215111776cac8e819458fce branch: master author: Victor Stinner committer: GitHub date: 2020-06-01T16:02:40+02:00 summary: bpo-40826: Add _Py_EnsureTstateNotNULL() macro (GH-20571) Add _Py_EnsureTstateNotNULL(tstate) macro: call Py_FatalError() if tstate is NULL, the error message contains the current function name. files: M Include/internal/pycore_pystate.h M Lib/test/test_capi.py M Python/ceval.c M Python/errors.c M Python/pystate.c M Python/sysmodule.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index d96ba31207001..7ac4ad5869b4c 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -86,6 +86,21 @@ _PyThreadState_GET(void) #undef PyThreadState_GET #define PyThreadState_GET() _PyThreadState_GET() +PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func); + +static inline void +_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) +{ + if (tstate == NULL) { + _Py_FatalError_TstateNULL(func); + } +} + +// Call Py_FatalError() if tstate is NULL +#define _Py_EnsureTstateNotNULL(tstate) \ + _Py_EnsureFuncTstateNotNULL(__func__, tstate) + + /* Get the current interpreter state. The macro is unsafe: it does not check for error and it can return NULL. @@ -96,7 +111,9 @@ _PyThreadState_GET(void) and _PyGILState_GetInterpreterStateUnsafe(). */ static inline PyInterpreterState* _PyInterpreterState_GET(void) { PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); +#ifdef Py_DEBUG + _Py_EnsureTstateNotNULL(tstate); +#endif return tstate->interp; } diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 44693b8fdd717..5b8b9f6a86f4b 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -68,7 +68,10 @@ def test_no_FatalError_infinite_loop(self): self.assertTrue(err.rstrip().startswith( b'Fatal Python error: ' b'PyThreadState_Get: ' - b'current thread state is NULL (released GIL?)')) + b'the function must be called with the GIL held, ' + b'but the GIL is released ' + b'(the current Python thread state is NULL)'), + err) def test_memoryview_from_NULL_pointer(self): self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) diff --git a/Python/ceval.c b/Python/ceval.c index a79773f85118a..01dd361e5035f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -240,16 +240,15 @@ UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) #endif #include "ceval_gil.h" -static void -ensure_tstate_not_null(const char *func, PyThreadState *tstate) +void _Py_NO_RETURN +_Py_FatalError_TstateNULL(const char *func) { - if (tstate == NULL) { - _Py_FatalErrorFunc(func, - "current thread state is NULL (released GIL?)"); - } + _Py_FatalErrorFunc(func, + "the function must be called with the GIL held, " + "but the GIL is released " + "(the current Python thread state is NULL)"); } - #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS int _PyEval_ThreadsInitialized(PyInterpreterState *interp) @@ -374,7 +373,7 @@ PyEval_AcquireLock(void) { _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); take_gil(tstate); } @@ -403,7 +402,7 @@ _PyEval_ReleaseLock(PyThreadState *tstate) void PyEval_AcquireThread(PyThreadState *tstate) { - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); take_gil(tstate); @@ -442,7 +441,7 @@ void _PyEval_ReInitThreads(_PyRuntimeState *runtime) { PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; @@ -486,7 +485,7 @@ PyEval_SaveThread(void) #else PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); #endif - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); struct _ceval_runtime_state *ceval = &runtime->ceval; struct _ceval_state *ceval2 = &tstate->interp->ceval; @@ -502,7 +501,7 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); take_gil(tstate); @@ -944,7 +943,7 @@ eval_frame_handle_pending(PyThreadState *tstate) PyObject* _Py_HOT_FUNCTION _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag) { - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); #ifdef DXPAIRS int lastopcode = 0; diff --git a/Python/errors.c b/Python/errors.c index 70365aaca585b..5d1725679c4bd 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1426,7 +1426,7 @@ void _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) { PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); + _Py_EnsureTstateNotNULL(tstate); PyObject *err_msg = NULL; PyObject *exc_type, *exc_value, *exc_tb; diff --git a/Python/pystate.c b/Python/pystate.c index 119fe31a84ba1..f92c55e747169 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,16 +39,6 @@ extern "C" { _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ (uintptr_t)(value)) -static void -ensure_tstate_not_null(const char *func, PyThreadState *tstate) -{ - if (tstate == NULL) { - _Py_FatalErrorFunc(func, - "current thread state is NULL (released GIL?)"); - } -} - - /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); @@ -431,7 +421,7 @@ PyInterpreterState * PyInterpreterState_Get(void) { PyThreadState *tstate = _PyThreadState_GET(); - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); PyInterpreterState *interp = tstate->interp; if (interp == NULL) { Py_FatalError("no current interpreter"); @@ -846,7 +836,7 @@ static void tstate_delete_common(PyThreadState *tstate, struct _gilstate_runtime_state *gilstate) { - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); PyInterpreterState *interp = tstate->interp; if (interp == NULL) { Py_FatalError("NULL interpreter"); @@ -897,7 +887,7 @@ PyThreadState_Delete(PyThreadState *tstate) void _PyThreadState_DeleteCurrent(PyThreadState *tstate) { - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; tstate_delete_common(tstate, gilstate); _PyRuntimeGILState_SetThreadState(gilstate, NULL); @@ -975,7 +965,7 @@ PyThreadState * PyThreadState_Get(void) { PyThreadState *tstate = _PyThreadState_GET(); - ensure_tstate_not_null(__func__, tstate); + _Py_EnsureTstateNotNULL(tstate); return tstate; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 914beb7e127fe..e3fe1436145b4 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -457,7 +457,7 @@ static PyObject * sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) { PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); + _Py_EnsureTstateNotNULL(tstate); if (argc == 0) { _PyErr_SetString(tstate, PyExc_TypeError, From webhook-mailer at python.org Mon Jun 1 11:44:08 2020 From: webhook-mailer at python.org (Zackery Spytz) Date: Mon, 01 Jun 2020 15:44:08 -0000 Subject: [Python-checkins] bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) Message-ID: https://github.com/python/cpython/commit/c8966667bbdb284c3780ef6cec8a3870935a6bb7 commit: c8966667bbdb284c3780ef6cec8a3870935a6bb7 branch: master author: Zackery Spytz committer: GitHub date: 2020-06-01T16:43:56+01:00 summary: bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 97e9cdfeb0939..b95a43c853c28 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -108,9 +108,7 @@ approximately 32,000 characters. Your administrator will need to activate the to ``1``. This allows the :func:`open` function, the :mod:`os` module and most other -path functionality to accept and return paths longer than 260 characters when -using strings. (Use of bytes as paths is deprecated on Windows, and this feature -is not available when using bytes.) +path functionality to accept and return paths longer than 260 characters. After changing the above option, no further configuration is required. From webhook-mailer at python.org Mon Jun 1 11:53:37 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 15:53:37 -0000 Subject: [Python-checkins] bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) Message-ID: https://github.com/python/cpython/commit/d0dc369a90e356bf2eba651816feb7ad736ce28a commit: d0dc369a90e356bf2eba651816feb7ad736ce28a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T08:53:33-07:00 summary: bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) (cherry picked from commit c8966667bbdb284c3780ef6cec8a3870935a6bb7) Co-authored-by: Zackery Spytz files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 636f48dfb012b..5114a26a57d07 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -108,9 +108,7 @@ approximately 32,000 characters. Your administrator will need to activate the to ``1``. This allows the :func:`open` function, the :mod:`os` module and most other -path functionality to accept and return paths longer than 260 characters when -using strings. (Use of bytes as paths is deprecated on Windows, and this feature -is not available when using bytes.) +path functionality to accept and return paths longer than 260 characters. After changing the above option, no further configuration is required. From webhook-mailer at python.org Mon Jun 1 11:53:43 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 15:53:43 -0000 Subject: [Python-checkins] bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) Message-ID: https://github.com/python/cpython/commit/d7f2fd2ae54161362c7f3d28bd7a1840a796e63d commit: d7f2fd2ae54161362c7f3d28bd7a1840a796e63d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T08:53:39-07:00 summary: bpo-40831: Remove an incorrect statement in the Windows docs (GH-20570) (cherry picked from commit c8966667bbdb284c3780ef6cec8a3870935a6bb7) Co-authored-by: Zackery Spytz files: M Doc/using/windows.rst diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index f5dddb5a37af8..819d3e8307498 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -108,9 +108,7 @@ approximately 32,000 characters. Your administrator will need to activate the to ``1``. This allows the :func:`open` function, the :mod:`os` module and most other -path functionality to accept and return paths longer than 260 characters when -using strings. (Use of bytes as paths is deprecated on Windows, and this feature -is not available when using bytes.) +path functionality to accept and return paths longer than 260 characters. After changing the above option, no further configuration is required. From webhook-mailer at python.org Mon Jun 1 12:12:32 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Mon, 01 Jun 2020 16:12:32 -0000 Subject: [Python-checkins] bpo-1635741: Port fcntl module to multiphase initialization (GH-20540) Message-ID: https://github.com/python/cpython/commit/e9684fac5a158be9806304a676e619857520a4dc commit: e9684fac5a158be9806304a676e619857520a4dc branch: master author: Dong-hee Na committer: GitHub date: 2020-06-02T01:12:24+09:00 summary: bpo-1635741: Port fcntl module to multiphase initialization (GH-20540) files: A Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst M Modules/fcntlmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst new file mode 100644 index 0000000000000..cd2bcb6e60877 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-30-23-23-35.bpo-1635741.0D-laM.rst @@ -0,0 +1 @@ +Port :mod:`fcntl` to multiphase initialization. diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 43f9b22f67207..39baea01ec84e 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -662,34 +662,31 @@ all_ins(PyObject* m) return 0; } +static int +fcntl_exec(PyObject *module) +{ + if (all_ins(module) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot fcntl_slots[] = { + {Py_mod_exec, fcntl_exec}, + {0, NULL} +}; static struct PyModuleDef fcntlmodule = { PyModuleDef_HEAD_INIT, - "fcntl", - module_doc, - -1, - fcntl_methods, - NULL, - NULL, - NULL, - NULL + .m_name = "fcntl", + .m_doc = module_doc, + .m_size = 0, + .m_methods = fcntl_methods, + .m_slots = fcntl_slots, }; PyMODINIT_FUNC PyInit_fcntl(void) { - PyObject *m; - - /* Create the module and add the functions and documentation */ - m = PyModule_Create(&fcntlmodule); - if (m == NULL) - return NULL; - - /* Add some symbolic constants to the module */ - if (all_ins(m) < 0) { - Py_DECREF(m); - return NULL; - } - - return m; + return PyModuleDef_Init(&fcntlmodule); } From webhook-mailer at python.org Mon Jun 1 12:54:28 2020 From: webhook-mailer at python.org (Hai Shi) Date: Mon, 01 Jun 2020 16:54:28 -0000 Subject: [Python-checkins] bpo-39593: Add test on ctypes cfield.c s_set() (GH-18424) Message-ID: https://github.com/python/cpython/commit/a97011b9b8c8111f42e1e7594081956136d848da commit: a97011b9b8c8111f42e1e7594081956136d848da branch: master author: Hai Shi committer: GitHub date: 2020-06-01T18:54:18+02:00 summary: bpo-39593: Add test on ctypes cfield.c s_set() (GH-18424) files: M Lib/ctypes/test/test_struct_fields.py M Modules/_ctypes/cfield.c diff --git a/Lib/ctypes/test/test_struct_fields.py b/Lib/ctypes/test/test_struct_fields.py index 8045cc82679cc..ee8415f3e630c 100644 --- a/Lib/ctypes/test/test_struct_fields.py +++ b/Lib/ctypes/test/test_struct_fields.py @@ -46,6 +46,14 @@ class Y(X): Y._fields_ = [] self.assertRaises(AttributeError, setattr, X, "_fields_", []) + def test_5(self): + class X(Structure): + _fields_ = (("char", c_char * 5),) + + x = X(b'#' * 5) + x.char = b'a\0b\0' + self.assertEqual(bytes(x), b'a\x00###') + # __set__ and __get__ should raise a TypeError in case their self # argument is not a ctype instance. def test___set__(self): diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 7f853190a785e..32a2beeb744f7 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1263,7 +1263,9 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) } data = PyBytes_AS_STRING(value); - size = strlen(data); /* XXX Why not Py_SIZE(value)? */ + // bpo-39593: Use strlen() to truncate the string at the first null character. + size = strlen(data); + if (size < length) { /* This will copy the terminating NUL character * if there is space for it. From webhook-mailer at python.org Mon Jun 1 13:21:49 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Mon, 01 Jun 2020 17:21:49 -0000 Subject: [Python-checkins] bpo-39943: Fix MSVC warnings in sre extension (GH-20508) Message-ID: https://github.com/python/cpython/commit/06e3a27a3c863495390a07c695171a8e62a6e0d2 commit: 06e3a27a3c863495390a07c695171a8e62a6e0d2 branch: master author: Ammar Askar committer: GitHub date: 2020-06-01T19:21:43+02:00 summary: bpo-39943: Fix MSVC warnings in sre extension (GH-20508) files: M Modules/_sre.c M Modules/sre_lib.h diff --git a/Modules/_sre.c b/Modules/_sre.c index 244e4f1f84dff..bdc427822d7e1 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -454,7 +454,10 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, return string; err: - PyMem_Del(state->mark); + /* We add an explicit cast here because MSVC has a bug when + compiling C code where it believes that `const void**` cannot be + safely casted to `void*`, see bpo-39943 for details. */ + PyMem_Del((void*) state->mark); state->mark = NULL; if (state->buffer.buf) PyBuffer_Release(&state->buffer); @@ -468,7 +471,8 @@ state_fini(SRE_STATE* state) PyBuffer_Release(&state->buffer); Py_XDECREF(state->string); data_stack_dealloc(state); - PyMem_Del(state->mark); + /* See above PyMem_Del for why we explicitly cast here. */ + PyMem_Del((void*) state->mark); state->mark = NULL; } diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 9cc786321c560..2657d8d82c6f1 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -448,12 +448,15 @@ do { \ state->data_stack_base += size; \ } while (0) +/* We add an explicit cast to memcpy here because MSVC has a bug when + compiling C code where it believes that `const void**` cannot be + safely casted to `void*`, see bpo-39943 for details. */ #define DATA_STACK_POP(state, data, size, discard) \ do { \ TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \ "(%" PY_FORMAT_SIZE_T "d)\n", \ data, state->data_stack_base-size, size)); \ - memcpy(data, state->data_stack+state->data_stack_base-size, size); \ + memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \ if (discard) \ state->data_stack_base -= size; \ } while (0) From webhook-mailer at python.org Mon Jun 1 13:26:38 2020 From: webhook-mailer at python.org (Huon Wilson) Date: Mon, 01 Jun 2020 17:26:38 -0000 Subject: [Python-checkins] bpo-40630: adjust tracemalloc.reset_peak docs for backport to 3.9 (GH-20546) Message-ID: https://github.com/python/cpython/commit/39de8e4b6f139f8d8284732bd7bb6e5ccced29fa commit: 39de8e4b6f139f8d8284732bd7bb6e5ccced29fa branch: master author: Huon Wilson committer: GitHub date: 2020-06-01T19:26:33+02:00 summary: bpo-40630: adjust tracemalloc.reset_peak docs for backport to 3.9 (GH-20546) files: D Misc/NEWS.d/next/Library/2020-05-15-13-40-15.bpo-40630.YXEX_M.rst M Doc/library/tracemalloc.rst M Doc/whatsnew/3.10.rst M Doc/whatsnew/3.9.rst diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index fba1caab455d7..20f668c728202 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -345,7 +345,7 @@ Functions See also :func:`get_traced_memory`. - .. versionadded:: 3.10 + .. versionadded:: 3.9 .. function:: get_tracemalloc_memory() diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 8a6b02179db17..95c5aa7ec6e6b 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -95,13 +95,6 @@ New Modules Improved Modules ================ -tracemalloc ------------ - -Added :func:`tracemalloc.reset_peak` to set the peak size of traced memory -blocks to the current size, to measure the peak of specific pieces of code. -(Contributed by Huon Wilson in :issue:`40630`.) - Optimizations ============= diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index a468130af1083..ccc84cced1090 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -562,6 +562,12 @@ Previously, :attr:`sys.stderr` was block-buffered when non-interactive. Now ``stderr`` defaults to always being line-buffered. (Contributed by Jendrik Seipp in :issue:`13601`.) +tracemalloc +----------- + +Added :func:`tracemalloc.reset_peak` to set the peak size of traced memory +blocks to the current size, to measure the peak of specific pieces of code. +(Contributed by Huon Wilson in :issue:`40630`.) typing ------ diff --git a/Misc/NEWS.d/next/Library/2020-05-15-13-40-15.bpo-40630.YXEX_M.rst b/Misc/NEWS.d/next/Library/2020-05-15-13-40-15.bpo-40630.YXEX_M.rst deleted file mode 100644 index bb2e7452d3cfb..0000000000000 --- a/Misc/NEWS.d/next/Library/2020-05-15-13-40-15.bpo-40630.YXEX_M.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added :func:`tracemalloc.reset_peak` to set the peak size of traced memory -blocks to the current size, to measure the peak of specific pieces of code. From webhook-mailer at python.org Mon Jun 1 14:34:24 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 01 Jun 2020 18:34:24 -0000 Subject: [Python-checkins] bpo-40826: PyOS_InterruptOccurred() requires GIL (GH-20578) Message-ID: https://github.com/python/cpython/commit/cbe129692293251e7fbcea9ff0d822824d90c140 commit: cbe129692293251e7fbcea9ff0d822824d90c140 branch: master author: Victor Stinner committer: GitHub date: 2020-06-01T20:34:15+02:00 summary: bpo-40826: PyOS_InterruptOccurred() requires GIL (GH-20578) PyOS_InterruptOccurred() now fails with a fatal error if it is called with the GIL released. files: A Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst M Modules/signalmodule.c diff --git a/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst b/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst new file mode 100644 index 0000000000000..0d7a36c3eb401 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-01-16-12-37.bpo-40826.zQzFoK.rst @@ -0,0 +1,2 @@ +:c:func:`PyOS_InterruptOccurred` now fails with a fatal error if it is +called with the GIL released. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8348971c353ba..6d340a68634af 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1782,8 +1782,9 @@ PyOS_FiniInterrupts(void) int PyOS_InterruptOccurred(void) { - PyInterpreterState *interp = _PyInterpreterState_GET(); - if (!_Py_ThreadCanHandleSignals(interp)) { + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; } From webhook-mailer at python.org Mon Jun 1 14:36:05 2020 From: webhook-mailer at python.org (Skip Montanaro) Date: Mon, 01 Jun 2020 18:36:05 -0000 Subject: [Python-checkins] bpo-39583: Remove superfluous "extern C" bits from Include/cpython/*.h (GH-18413) Message-ID: https://github.com/python/cpython/commit/b4d5a5cca29426a282e8f1e64b2271fdd1f0a23e commit: b4d5a5cca29426a282e8f1e64b2271fdd1f0a23e branch: master author: Skip Montanaro committer: GitHub date: 2020-06-01T20:35:56+02:00 summary: bpo-39583: Remove superfluous "extern C" bits from Include/cpython/*.h (GH-18413) files: A Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst M Include/cpython/abstract.h M Include/cpython/ceval.h M Include/cpython/dictobject.h M Include/cpython/fileobject.h M Include/cpython/frameobject.h M Include/cpython/import.h M Include/cpython/initconfig.h M Include/cpython/interpreteridobject.h M Include/cpython/listobject.h M Include/cpython/object.h M Include/cpython/objimpl.h M Include/cpython/pyerrors.h M Include/cpython/pylifecycle.h M Include/cpython/pymem.h M Include/cpython/pystate.h M Include/cpython/sysmodule.h M Include/cpython/traceback.h M Include/cpython/tupleobject.h M Include/cpython/unicodeobject.h diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index aa72f998b701c..b5b6e4819788c 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* === Object Protocol ================================================== */ #ifdef PY_SSIZE_T_CLEAN @@ -380,8 +376,4 @@ PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *); /* Same as PyNumber_Index but can return an instance of a subclass of int. */ -PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); - -#ifdef __cplusplus -} -#endif +PyAPI_FUNC(PyObject *) _PyNumber_Index(PyObject *o); \ No newline at end of file diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index e1922a677bd38..06338928f6738 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); @@ -32,7 +28,3 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index e33a0d156fead..ffe0e97fb35f3 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct _dictkeysobject PyDictKeysObject; /* The ma_values pointer is NULL for a combined table @@ -86,7 +82,3 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index 57eac13c064c2..4f2408c7e8760 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 @@ -26,7 +22,3 @@ typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index 36a51baae8784..c76fbe0616cb2 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -4,10 +4,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { int b_type; /* what kind of block this is */ int b_handler; /* where to jump to find handler */ @@ -78,7 +74,3 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/import.h b/Include/cpython/import.h index c1b47121f1246..3b20a74c855db 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyMODINIT_FUNC PyInit__imp(void); PyAPI_FUNC(int) _PyImport_IsInitialized(PyInterpreterState *); @@ -44,7 +40,3 @@ struct _frozen { collection of frozen modules: */ PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index df93a5539d48b..e9c2e6bec3861 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -1,9 +1,6 @@ #ifndef Py_PYCORECONFIG_H #define Py_PYCORECONFIG_H #ifndef Py_LIMITED_API -#ifdef __cplusplus -extern "C" { -#endif /* --- PyStatus ----------------------------------------------- */ @@ -438,8 +435,5 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items); -#ifdef __cplusplus -} -#endif #endif /* !Py_LIMITED_API */ #endif /* !Py_PYCORECONFIG_H */ diff --git a/Include/cpython/interpreteridobject.h b/Include/cpython/interpreteridobject.h index 67ec5873542d8..5076584209b90 100644 --- a/Include/cpython/interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Interpreter ID Object */ PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; @@ -13,7 +9,3 @@ PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index 74fe3301a7ab7..b1af5f6764427 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { PyObject_VAR_HEAD /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ @@ -37,7 +33,3 @@ PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); #define PyList_SET_ITEM(op, i, v) (_PyList_CAST(op)->ob_item[i] = (v)) #define PyList_GET_SIZE(op) Py_SIZE(_PyList_CAST(op)) #define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 444f832f5bd8d..304cfbfc37dff 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void) _Py_NewReference(PyObject *op); #ifdef Py_TRACE_REFS @@ -548,7 +544,3 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); * unconditionally */ #define Py_TRASHCAN_SAFE_BEGIN(op) Py_TRASHCAN_BEGIN_CONDITION(op, 1) #define Py_TRASHCAN_SAFE_END(op) Py_TRASHCAN_END - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index b835936db7011..ca4009bcdb4c1 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a @@ -139,7 +135,3 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index dd3c2caa0cc04..3f347dc2e2d62 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Error objects */ /* PyException_HEAD defines the initial segment of every exception class. */ @@ -188,7 +184,3 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( ...); #define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message) - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index eb523b82e182d..f38ec5a4ae399 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Only used by applications that embed the interpreter and need to * override the standard encoding determination mechanism */ @@ -66,7 +62,3 @@ PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/pymem.h b/Include/cpython/pymem.h index 79f063b121753..61d719584584e 100644 --- a/Include/cpython/pymem.h +++ b/Include/cpython/pymem.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); @@ -102,7 +98,3 @@ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, The function does nothing if Python is not compiled is debug mode. */ PyAPI_FUNC(void) PyMem_SetupDebugHooks(void); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index f292da1d3c6c5..42a7fc163064d 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - #include "cpython/initconfig.h" PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); @@ -257,7 +253,3 @@ typedef int (*crossinterpdatafunc)(PyObject *, struct _xid *); PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h index 1802b5b300018..fc4c899b3fe3d 100644 --- a/Include/cpython/sysmodule.h +++ b/Include/cpython/sysmodule.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); @@ -18,7 +14,3 @@ PyAPI_FUNC(int) PySys_Audit( const char *argFormat, ...); PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/traceback.h b/Include/cpython/traceback.h index 837470c3ba2bc..aac5b42c344d3 100644 --- a/Include/cpython/traceback.h +++ b/Include/cpython/traceback.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct _traceback { PyObject_HEAD struct _traceback *tb_next; @@ -16,7 +12,3 @@ typedef struct _traceback { PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/tupleobject.h b/Include/cpython/tupleobject.h index 1565f2a5c3d98..51dcd4237be18 100644 --- a/Include/cpython/tupleobject.h +++ b/Include/cpython/tupleobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { PyObject_VAR_HEAD /* ob_item contains space for 'ob_size' elements. @@ -30,7 +26,3 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); #define PyTuple_SET_ITEM(op, i, v) (_PyTuple_CAST(op)->ob_item[i] = v) PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); - -#ifdef __cplusplus -} -#endif diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 4fd674ffea36e..3b49ce7759037 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -2,10 +2,6 @@ # error "this header file must not be included directly" #endif -#ifdef __cplusplus -extern "C" { -#endif - /* Py_UNICODE was the native Unicode storage format (code unit) used by Python and represents a single Unicode element in the Unicode type. With PEP 393, Py_UNICODE is deprecated and replaced with a @@ -1221,7 +1217,3 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); - -#ifdef __cplusplus -} -#endif diff --git a/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst b/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst new file mode 100644 index 0000000000000..1c9f44f7443c1 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-08-08-01-35.bpo-39583.qURKSl.rst @@ -0,0 +1 @@ +Remove superfluous "extern C" declarations from ``Include/cpython/*.h``. From webhook-mailer at python.org Mon Jun 1 14:59:44 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 01 Jun 2020 18:59:44 -0000 Subject: [Python-checkins] bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20579) Message-ID: https://github.com/python/cpython/commit/c353764fd564e401cf47a5d9efab18c72c60014e commit: c353764fd564e401cf47a5d9efab18c72c60014e branch: master author: Victor Stinner committer: GitHub date: 2020-06-01T20:59:35+02:00 summary: bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20579) Fix GIL usage in PyOS_Readline(): lock the GIL to set an exception. Pass tstate to my_fgets() and _PyOS_WindowsConsoleReadline(). Cleanup these functions. files: A Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst M Parser/myreadline.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst new file mode 100644 index 0000000000000..f79f20d21d49c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst @@ -0,0 +1 @@ +Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception. diff --git a/Parser/myreadline.c b/Parser/myreadline.c index 04c2793225cb3..d2787f0d345cf 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -27,22 +27,24 @@ int (*PyOS_InputHook)(void) = NULL; except if PyOS_InterruptOccurred() returns true. */ static int -my_fgets(char *buf, int len, FILE *fp) +my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) { #ifdef MS_WINDOWS HANDLE hInterruptEvent; #endif - char *p; - int err; while (1) { - if (PyOS_InputHook != NULL) + if (PyOS_InputHook != NULL) { (void)(PyOS_InputHook)(); + } + errno = 0; clearerr(fp); - p = fgets(buf, len, fp); - if (p != NULL) + char *p = fgets(buf, len, fp); + if (p != NULL) { return 0; /* No error */ - err = errno; + } + int err = errno; + #ifdef MS_WINDOWS /* Ctrl-C anywhere on the line or Ctrl-Z if the only character on a line will set ERROR_OPERATION_ABORTED. Under normal @@ -68,22 +70,26 @@ my_fgets(char *buf, int len, FILE *fp) } } #endif /* MS_WINDOWS */ + if (feof(fp)) { clearerr(fp); return -1; /* EOF */ } + #ifdef EINTR if (err == EINTR) { - int s; - PyEval_RestoreThread(_PyOS_ReadlineTState); - s = PyErr_CheckSignals(); + PyEval_RestoreThread(tstate); + int s = PyErr_CheckSignals(); PyEval_SaveThread(); - if (s < 0) - return 1; - /* try again */ + + if (s < 0) { + return 1; + } + /* try again */ continue; } #endif + if (PyOS_InterruptOccurred()) { return 1; /* Interrupt */ } @@ -98,7 +104,7 @@ my_fgets(char *buf, int len, FILE *fp) extern char _get_console_type(HANDLE handle); char * -_PyOS_WindowsConsoleReadline(HANDLE hStdIn) +_PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) { static wchar_t wbuf_local[1024 * 16]; const DWORD chunk_size = 1024; @@ -133,11 +139,12 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) == WAIT_OBJECT_0) { ResetEvent(hInterruptEvent); - PyEval_RestoreThread(_PyOS_ReadlineTState); + PyEval_RestoreThread(tstate); s = PyErr_CheckSignals(); PyEval_SaveThread(); - if (s < 0) + if (s < 0) { goto exit; + } } break; } @@ -150,17 +157,22 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (wbuf == wbuf_local) { wbuf[total_read] = '\0'; wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t)); - if (wbuf) + if (wbuf) { wcscpy_s(wbuf, wbuflen, wbuf_local); + } else { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } } else { wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t)); if (tmp == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } wbuf = tmp; @@ -169,33 +181,45 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (wbuf[0] == '\x1a') { buf = PyMem_RawMalloc(1); - if (buf) + if (buf) { buf[0] = '\0'; + } else { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); } goto exit; } - u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, NULL, 0, NULL, NULL); + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + NULL, 0, + NULL, NULL); buf = PyMem_RawMalloc(u8len + 1); if (buf == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } - u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, buf, u8len, NULL, NULL); + + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + buf, u8len, + NULL, NULL); buf[u8len] = '\0'; exit: - if (wbuf != wbuf_local) + if (wbuf != wbuf_local) { PyMem_RawFree(wbuf); + } if (err) { - PyEval_RestoreThread(_PyOS_ReadlineTState); + PyEval_RestoreThread(tstate); PyErr_SetFromWindowsErr(err); PyEval_SaveThread(); } - return buf; } @@ -209,6 +233,8 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { size_t n; char *p, *pr; + PyThreadState *tstate = _PyOS_ReadlineTState; + assert(tstate != NULL); #ifdef MS_WINDOWS if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { @@ -230,7 +256,9 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (wlen) { wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t)); if (wbuf == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1, @@ -249,7 +277,7 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) } } clearerr(sys_stdin); - return _PyOS_WindowsConsoleReadline(hStdIn); + return _PyOS_WindowsConsoleReadline(tstate, hStdIn); } } #endif @@ -257,16 +285,19 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) n = 100; p = (char *)PyMem_RawMalloc(n); if (p == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } fflush(sys_stdout); - if (prompt) + if (prompt) { fprintf(stderr, "%s", prompt); + } fflush(stderr); - switch (my_fgets(p, (int)n, sys_stdin)) { + switch (my_fgets(tstate, p, (int)n, sys_stdin)) { case 0: /* Normal case */ break; case 1: /* Interrupt */ @@ -278,29 +309,40 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) *p = '\0'; break; } + n = strlen(p); while (n > 0 && p[n-1] != '\n') { size_t incr = n+2; if (incr > INT_MAX) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_SetString(PyExc_OverflowError, "input line too long"); + PyEval_SaveThread(); return NULL; } + pr = (char *)PyMem_RawRealloc(p, n + incr); if (pr == NULL) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } p = pr; - if (my_fgets(p+n, (int)incr, sys_stdin) != 0) + + if (my_fgets(tstate, p+n, (int)incr, sys_stdin) != 0) { break; + } n += strlen(p+n); } + pr = (char *)PyMem_RawRealloc(p, n+1); if (pr == NULL) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } return pr; @@ -323,7 +365,8 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) char *rv, *res; size_t len; - if (_PyOS_ReadlineTState == _PyThreadState_GET()) { + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyOS_ReadlineTState == tstate) { PyErr_SetString(PyExc_RuntimeError, "can't re-enter readline"); return NULL; @@ -342,7 +385,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) } } - _PyOS_ReadlineTState = _PyThreadState_GET(); + _PyOS_ReadlineTState = tstate; Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_PyOS_ReadlineLock, 1); From webhook-mailer at python.org Mon Jun 1 17:17:28 2020 From: webhook-mailer at python.org (Steve Dower) Date: Mon, 01 Jun 2020 21:17:28 -0000 Subject: [Python-checkins] Ensure correct version of Sphinx is used for Windows builds (GH-20582) Message-ID: https://github.com/python/cpython/commit/fe5dd78182dbf4937bcc2b113ca7526bfad0192b commit: fe5dd78182dbf4937bcc2b113ca7526bfad0192b branch: master author: Steve Dower committer: GitHub date: 2020-06-01T22:17:23+01:00 summary: Ensure correct version of Sphinx is used for Windows builds (GH-20582) files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 6f8f172e95eb8..7fde063642771 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx + %PYTHON% -m pip install sphinx==2.2.0 if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" From webhook-mailer at python.org Mon Jun 1 17:23:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 21:23:28 -0000 Subject: [Python-checkins] Ensure correct version of Sphinx is used for Windows builds (GH-20582) Message-ID: https://github.com/python/cpython/commit/b640ca1f3e52771dd70a3442780c3eb8d902f3b3 commit: b640ca1f3e52771dd70a3442780c3eb8d902f3b3 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T14:23:18-07:00 summary: Ensure correct version of Sphinx is used for Windows builds (GH-20582) (cherry picked from commit fe5dd78182dbf4937bcc2b113ca7526bfad0192b) Co-authored-by: Steve Dower files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 2f21e6d52ef91..63e0bd7236475 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx + %PYTHON% -m pip install sphinx==2.2.0 if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" From webhook-mailer at python.org Mon Jun 1 17:25:37 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 01 Jun 2020 21:25:37 -0000 Subject: [Python-checkins] Ensure correct version of Sphinx is used for Windows builds (GH-20582) Message-ID: https://github.com/python/cpython/commit/139f1bafcf0bf48f8f55464523a4c5e50ddb50fd commit: 139f1bafcf0bf48f8f55464523a4c5e50ddb50fd branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-01T14:25:32-07:00 summary: Ensure correct version of Sphinx is used for Windows builds (GH-20582) (cherry picked from commit fe5dd78182dbf4937bcc2b113ca7526bfad0192b) Co-authored-by: Steve Dower files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 6f8f172e95eb8..7fde063642771 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx + %PYTHON% -m pip install sphinx==2.2.0 if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" From webhook-mailer at python.org Mon Jun 1 21:17:53 2020 From: webhook-mailer at python.org (Sanyam Khurana) Date: Tue, 02 Jun 2020 01:17:53 -0000 Subject: [Python-checkins] bpo-26543: Fix IMAP4.noop when debug mode is enabled (GH-15206) Message-ID: https://github.com/python/cpython/commit/8a3d2af997e3702eac4c5b012537be39ada36888 commit: 8a3d2af997e3702eac4c5b012537be39ada36888 branch: master author: Sanyam Khurana <8039608+CuriousLearner at users.noreply.github.com> committer: GitHub date: 2020-06-02T03:17:45+02:00 summary: bpo-26543: Fix IMAP4.noop when debug mode is enabled (GH-15206) files: A Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst M Lib/imaplib.py M Lib/test/test_imaplib.py diff --git a/Lib/imaplib.py b/Lib/imaplib.py index d9720f20c3902..73184396d894a 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -1251,13 +1251,12 @@ def _mesg(self, s, secs=None): sys.stderr.write(' %s.%02d %s\n' % (tm, (secs*100)%100, s)) sys.stderr.flush() - def _dump_ur(self, dict): - # Dump untagged responses (in `dict'). - l = dict.items() - if not l: return - t = '\n\t\t' - l = map(lambda x:'%s: "%s"' % (x[0], x[1][0] and '" "'.join(x[1]) or ''), l) - self._mesg('untagged responses dump:%s%s' % (t, t.join(l))) + def _dump_ur(self, untagged_resp_dict): + if not untagged_resp_dict: + return + items = (f'{key}: {value!r}' + for key, value in untagged_resp_dict.items()) + self._mesg('untagged responses dump:' + '\n\t\t'.join(items)) def _log(self, line): # Keep log of last `_cmd_log_len' interactions for debugging. diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 0fcc1fb99a289..f93efba794952 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -933,6 +933,20 @@ def test_with_statement_logout(self): self.assertIsNone(server.logged) self.assertIsNone(server.logged) + @threading_helper.reap_threads + @cpython_only + def test_dump_ur(self): + # See: http://bugs.python.org/issue26543 + untagged_resp_dict = {'READ-WRITE': [b'']} + + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address) as imap: + with mock.patch.object(imap, '_mesg') as mock_mesg: + imap._dump_ur(untagged_resp_dict) + mock_mesg.assert_called_with( + "untagged responses dump:READ-WRITE: [b'']" + ) + @unittest.skipUnless(ssl, "SSL not available") class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests): diff --git a/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst b/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst new file mode 100644 index 0000000000000..8715b8d79cace --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-08-11-16-28-03.bpo-26543.X-TJZO.rst @@ -0,0 +1 @@ +Fix :meth:`IMAP4.noop()` when debug mode is enabled (ex: ``imaplib.Debug = 3``). From webhook-mailer at python.org Tue Jun 2 04:17:29 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Tue, 02 Jun 2020 08:17:29 -0000 Subject: [Python-checkins] Fix MSVC warnings in pythonrun.c (#GH-0587) Message-ID: https://github.com/python/cpython/commit/90d297012b3848454cbd00dde954e3ea1a09e86f commit: 90d297012b3848454cbd00dde954e3ea1a09e86f branch: master author: Ammar Askar committer: GitHub date: 2020-06-02T09:17:24+01:00 summary: Fix MSVC warnings in pythonrun.c (#GH-0587) files: M Python/pythonrun.c diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 160f44d38e2e1..cb0e3b02e163a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -478,9 +478,9 @@ PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags) static int parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, - int *lineno, int *offset, PyObject **text) + Py_ssize_t *lineno, Py_ssize_t *offset, PyObject **text) { - int hold; + Py_ssize_t hold; PyObject *v; _Py_IDENTIFIER(msg); _Py_IDENTIFIER(filename); @@ -513,7 +513,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, v = _PyObject_GetAttrId(err, &PyId_lineno); if (!v) goto finally; - hold = _PyLong_AsInt(v); + hold = PyLong_AsSsize_t(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) goto finally; @@ -526,7 +526,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, *offset = -1; Py_DECREF(v); } else { - hold = _PyLong_AsInt(v); + hold = PyLong_AsSsize_t(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) goto finally; @@ -552,7 +552,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, } static void -print_error_text(PyObject *f, int offset, PyObject *text_obj) +print_error_text(PyObject *f, Py_ssize_t offset, PyObject *text_obj) { /* Convert text to a char pointer; return if error */ const char *text = PyUnicode_AsUTF8(text_obj); @@ -586,7 +586,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) break; } Py_ssize_t inl = nl - text; - if (inl >= (Py_ssize_t)offset) { + if (inl >= offset) { break; } inl += 1; @@ -833,7 +833,7 @@ print_exception(PyObject *f, PyObject *value) _PyObject_HasAttrId(value, &PyId_print_file_and_line)) { PyObject *message, *filename, *text; - int lineno, offset; + Py_ssize_t lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); @@ -843,7 +843,7 @@ print_exception(PyObject *f, PyObject *value) Py_DECREF(value); value = message; - line = PyUnicode_FromFormat(" File \"%S\", line %d\n", + line = PyUnicode_FromFormat(" File \"%S\", line %zd\n", filename, lineno); Py_DECREF(filename); if (line != NULL) { From webhook-mailer at python.org Tue Jun 2 04:19:57 2020 From: webhook-mailer at python.org (Batuhan Taskaya) Date: Tue, 02 Jun 2020 08:19:57 -0000 Subject: [Python-checkins] bpo-40244: Remove XLC's support from the noreturn flag (GH-20588) Message-ID: https://github.com/python/cpython/commit/033d10bd21d962a59c6c4fc503092046baa451a1 commit: 033d10bd21d962a59c6c4fc503092046baa451a1 branch: master author: Batuhan Taskaya committer: GitHub date: 2020-06-02T01:19:52-07:00 summary: bpo-40244: Remove XLC's support from the noreturn flag (GH-20588) Automerge-Triggered-By: @pablogsal files: M Include/pyport.h diff --git a/Include/pyport.h b/Include/pyport.h index 63d3b81de5d23..bdbd0c942f682 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -829,10 +829,10 @@ extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler; #endif /* Mark a function which cannot return. Example: + PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); - PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); */ + XLC support is intentionally omitted due to bpo-40244 */ #if defined(__clang__) || \ - defined(__xlc__) || \ (defined(__GNUC__) && \ ((__GNUC__ >= 3) || \ (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))) From webhook-mailer at python.org Tue Jun 2 06:03:02 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 10:03:02 -0000 Subject: [Python-checkins] bpo-40241: What's New in Python 3.9: opaque PyGC_Head (GH-20586) Message-ID: https://github.com/python/cpython/commit/337d3103a2344e1fec75985e85fabcbdedac7d26 commit: 337d3103a2344e1fec75985e85fabcbdedac7d26 branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T12:02:58+02:00 summary: bpo-40241: What's New in Python 3.9: opaque PyGC_Head (GH-20586) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ccc84cced1090..b20cd14565ae1 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -1098,6 +1098,10 @@ Porting to Python 3.9 and refers to a constant string. (Contributed by Serhiy Storchaka in :issue:`38650`.) +* The :c:type:`PyGC_Head` structure is now opaque. It is only defined in the + internal C API (``pycore_gc.h``). + (Contributed by Victor Stinner in :issue:`40241`.) + Removed ------- From webhook-mailer at python.org Tue Jun 2 07:33:19 2020 From: webhook-mailer at python.org (Srinivas Reddy Thatiparthy =?utf-8?q??= =?utf-8?b?KOCwtuCxjeCwsOCxgOCwqOCwv+CwteCwvuCwuOCxjSAg4LCw4LGG4LCh?= =?utf-8?b?4LGN4LCh4LC/IOCwpOCwvuCwn+Cwv+CwquCwsOCxjeCwpOCwvyk=?=) Date: Tue, 02 Jun 2020 11:33:19 -0000 Subject: [Python-checkins] bpo-35078: Allow customization of CSS class name of a month in calendar module (gh-10137) Message-ID: https://github.com/python/cpython/commit/85339f5c220a5e79c47c3a33c93f1dca5c59c52e commit: 85339f5c220a5e79c47c3a33c93f1dca5c59c52e branch: master author: Srinivas Reddy Thatiparthy (?????????? ?????? ?????????) committer: GitHub date: 2020-06-02T13:33:09+02:00 summary: bpo-35078: Allow customization of CSS class name of a month in calendar module (gh-10137) Refactor formatweekday(), formatmonthname() methods in LocaleHTMLCalendar and LocaleTextCalendar classes in calendar module to call the base class methods. This enables customizable CSS classes for LocaleHTMLCalendar and LocaleTextCalendar. Patch by Srinivas Reddy Thatiparthy files: A Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst M Lib/calendar.py M Lib/test/test_calendar.py diff --git a/Lib/calendar.py b/Lib/calendar.py index 7550d52c0a94a..7311a0173729e 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -571,19 +571,11 @@ def __init__(self, firstweekday=0, locale=None): def formatweekday(self, day, width): with different_locale(self.locale): - if width >= 9: - names = day_name - else: - names = day_abbr - name = names[day] - return name[:width].center(width) + return super().formatweekday(day, width) def formatmonthname(self, theyear, themonth, width, withyear=True): with different_locale(self.locale): - s = month_name[themonth] - if withyear: - s = "%s %r" % (s, theyear) - return s.center(width) + return super().formatmonthname(theyear, themonth, width, withyear) class LocaleHTMLCalendar(HTMLCalendar): @@ -601,16 +593,11 @@ def __init__(self, firstweekday=0, locale=None): def formatweekday(self, day): with different_locale(self.locale): - s = day_abbr[day] - return '%s' % (self.cssclasses[day], s) + return super().formatweekday(day) def formatmonthname(self, theyear, themonth, withyear=True): with different_locale(self.locale): - s = month_name[themonth] - if withyear: - s = '%s %s' % (s, theyear) - return '%s' % s - + return super().formatmonthname(theyear, themonth, withyear) # Support for old module level interface c = TextCalendar() diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 6241d114d3382..7c7ec1c931aa4 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -564,6 +564,30 @@ def test_locale_calendars(self): new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) self.assertEqual(old_october, new_october) + def test_locale_html_calendar_custom_css_class_month_name(self): + try: + cal = calendar.LocaleHTMLCalendar(locale='') + local_month = cal.formatmonthname(2010, 10, 10) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') + self.assertIn('class="month"', local_month) + cal.cssclass_month_head = "text-center month" + local_month = cal.formatmonthname(2010, 10, 10) + self.assertIn('class="text-center month"', local_month) + + def test_locale_html_calendar_custom_css_class_weekday(self): + try: + cal = calendar.LocaleHTMLCalendar(locale='') + local_weekday = cal.formatweekday(6) + except locale.Error: + # cannot set the system default locale -- skip rest of test + raise unittest.SkipTest('cannot set the system default locale') + self.assertIn('class="sun"', local_weekday) + cal.cssclasses_weekday_head = ["mon2", "tue2", "wed2", "thu2", "fri2", "sat2", "sun2"] + local_weekday = cal.formatweekday(6) + self.assertIn('class="sun2"', local_weekday) + def test_itermonthdays3(self): # ensure itermonthdays3 doesn't overflow after datetime.MAXYEAR list(calendar.Calendar().itermonthdays3(datetime.MAXYEAR, 12)) diff --git a/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst b/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst new file mode 100644 index 0000000000000..123f9dabde913 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-10-27-09-37-03.bpo-35078.kweA3R.rst @@ -0,0 +1,3 @@ +Refactor formatweekday, formatmonthname methods in LocaleHTMLCalendar and LocaleTextCalendar classes in calendar module to call the base class methods.This enables customizable CSS classes for LocaleHTMLCalendar. +Patch by Srinivas Reddy Thatiparthy + From webhook-mailer at python.org Tue Jun 2 08:03:34 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 12:03:34 -0000 Subject: [Python-checkins] bpo-40839: PyDict_GetItem() requires the GIL (GH-20580) Message-ID: https://github.com/python/cpython/commit/59d3dce69b0a4f6ee17578ae68037cc7ae90936f commit: 59d3dce69b0a4f6ee17578ae68037cc7ae90936f branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T14:03:25+02:00 summary: bpo-40839: PyDict_GetItem() requires the GIL (GH-20580) Calling PyDict_GetItem() without GIL held had been allowed for historical reason. It is no longer allowed. files: A Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst M Doc/c-api/dict.rst M Doc/whatsnew/3.10.rst M Objects/dictobject.c diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 2fb29cdd61778..7493837ac622f 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -100,6 +100,10 @@ Dictionary Objects :meth:`__eq__` methods will get suppressed. To get error reporting use :c:func:`PyDict_GetItemWithError()` instead. + .. versionchanged:: 3.10 + Calling this API without :term:`GIL` held had been allowed for historical + reason. It is no longer allowed. + .. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 95c5aa7ec6e6b..0b656475b7167 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -148,5 +148,9 @@ Porting to Python 3.10 see :c:func:`Py_SET_SIZE()` (available since Python 3.9). (Contributed by Victor Stinner in :issue:`39573`.) +* Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed + for historical reason. It is no longer allowed. + (Contributed by Victor Stinner in :issue:`40839`.) + Removed ------- diff --git a/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst b/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst new file mode 100644 index 0000000000000..5de2f40c14eca --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-01-20-47-49.bpo-40839.bAi52Z.rst @@ -0,0 +1,2 @@ +Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed for +historical reason. It is no longer allowed. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 809a5ed778737..c4d5da51f3193 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -112,7 +112,8 @@ converting the dict to the combined table. #include "Python.h" #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() -#include "pycore_object.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_pyerrors.h" // _PyErr_Fetch() #include "pycore_pystate.h" // _PyThreadState_GET() #include "dict-common.h" #include "stringlib/eq.h" // unicode_eq() @@ -1387,14 +1388,12 @@ _PyDict_NewPresized(Py_ssize_t minused) PyObject * PyDict_GetItem(PyObject *op, PyObject *key) { - Py_hash_t hash; - Py_ssize_t ix; + if (!PyDict_Check(op)) { + return NULL; + } PyDictObject *mp = (PyDictObject *)op; - PyThreadState *tstate; - PyObject *value; - if (!PyDict_Check(op)) - return NULL; + Py_hash_t hash; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -1405,28 +1404,26 @@ PyDict_GetItem(PyObject *op, PyObject *key) } } - /* We can arrive here with a NULL tstate during initialization: try - running "python -Wi" for an example related to string interning. - Let's just hope that no exception occurs then... This must be - _PyThreadState_GET() and not PyThreadState_Get() because the latter - abort Python if tstate is NULL. */ - tstate = _PyThreadState_GET(); - if (tstate != NULL && tstate->curexc_type != NULL) { - /* preserve the existing exception */ - PyObject *err_type, *err_value, *err_tb; - PyErr_Fetch(&err_type, &err_value, &err_tb); - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); - /* ignore errors */ - PyErr_Restore(err_type, err_value, err_tb); - if (ix < 0) - return NULL; - } - else { - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); - if (ix < 0) { - PyErr_Clear(); - return NULL; - } + PyThreadState *tstate = _PyThreadState_GET(); +#ifdef Py_DEBUG + // bpo-40839: Before Python 3.10, it was possible to call PyDict_GetItem() + // with the GIL released. + _Py_EnsureTstateNotNULL(tstate); +#endif + + /* Preserve the existing exception */ + PyObject *exc_type, *exc_value, *exc_tb; + PyObject *value; + Py_ssize_t ix; + + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value); + + /* Ignore any exception raised by the lookup */ + _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + + if (ix < 0) { + return NULL; } return value; } From webhook-mailer at python.org Tue Jun 2 08:40:01 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 12:40:01 -0000 Subject: [Python-checkins] bpo-39465: Cleanup _PyUnicode_FromId() code (GH-20595) Message-ID: https://github.com/python/cpython/commit/297257f7bc198e2dc8e0866b539c73ff1a5cc588 commit: 297257f7bc198e2dc8e0866b539c73ff1a5cc588 branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T14:39:45+02:00 summary: bpo-39465: Cleanup _PyUnicode_FromId() code (GH-20595) Work on a local variable before filling _Py_Identifier members. files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 511640438d015..e69bf01251ced 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2275,17 +2275,23 @@ PyUnicode_FromString(const char *u) PyObject * _PyUnicode_FromId(_Py_Identifier *id) { - if (!id->object) { - id->object = PyUnicode_DecodeUTF8Stateful(id->string, - strlen(id->string), - NULL, NULL); - if (!id->object) - return NULL; - PyUnicode_InternInPlace(&id->object); - assert(!id->next); - id->next = static_strings; - static_strings = id; + if (id->object) { + return id->object; + } + + PyObject *obj; + obj = PyUnicode_DecodeUTF8Stateful(id->string, + strlen(id->string), + NULL, NULL); + if (!obj) { + return NULL; } + PyUnicode_InternInPlace(&obj); + + assert(!id->next); + id->object = obj; + id->next = static_strings; + static_strings = id; return id->object; } From webhook-mailer at python.org Tue Jun 2 09:51:46 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 13:51:46 -0000 Subject: [Python-checkins] PyOS_AfterFork_Child() uses PyStatus (GH-20596) Message-ID: https://github.com/python/cpython/commit/26881c8fae3b67db3a01d335d3ae7356a29b433e commit: 26881c8fae3b67db3a01d335d3ae7356a29b433e branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T15:51:37+02:00 summary: PyOS_AfterFork_Child() uses PyStatus (GH-20596) PyOS_AfterFork_Child() helper functions now return a PyStatus: PyOS_AfterFork_Child() is now responsible to handle errors. * Move _PySignal_AfterFork() to the internal C API * Add #ifdef HAVE_FORK on _PyGILState_Reinit(), _PySignal_AfterFork() and _PyInterpreterState_DeleteExceptMain(). files: M Include/internal/pycore_ceval.h M Include/internal/pycore_import.h M Include/internal/pycore_pystate.h M Include/internal/pycore_runtime.h M Include/intrcheck.h M Modules/posixmodule.c M Modules/signalmodule.c M Python/ceval.c M Python/import.c M Python/pystate.c diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 368990099089f..2da0154525b1c 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -25,7 +25,7 @@ PyAPI_FUNC(int) _PyEval_AddPendingCall( void *arg); PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyThreadState *tstate); #ifdef HAVE_FORK -extern void _PyEval_ReInitThreads(struct pyruntimestate *runtime); +extern PyStatus _PyEval_ReInitThreads(struct pyruntimestate *runtime); #endif PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( PyThreadState *tstate, diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index b011ea4425112..35a67abebac6f 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -11,7 +11,7 @@ PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( ); #ifdef HAVE_FORK -extern void _PyImport_ReInitLock(void); +extern PyStatus _PyImport_ReInitLock(void); #endif extern void _PyImport_Cleanup(PyThreadState *tstate); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 7ac4ad5869b4c..423c8113d7ac0 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -131,9 +131,12 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( PyThreadState *newts); PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); -PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); +#ifdef HAVE_FORK +extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); +extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime); +extern void _PySignal_AfterFork(void); +#endif PyAPI_FUNC(int) _PyState_AddModule( diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index ebdc12b23a9ca..3a01d64e63d81 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -120,7 +120,7 @@ PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); #ifdef HAVE_FORK -PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); +extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); #endif /* Initialize _PyRuntimeState. diff --git a/Include/intrcheck.h b/Include/intrcheck.h index e5bf5a834e44c..88f2a7076ce37 100644 --- a/Include/intrcheck.h +++ b/Include/intrcheck.h @@ -1,4 +1,3 @@ - #ifndef Py_INTRCHECK_H #define Py_INTRCHECK_H #ifdef __cplusplus @@ -19,7 +18,6 @@ Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyOS_IsMainThread(void); -PyAPI_FUNC(void) _PySignal_AfterFork(void); #ifdef MS_WINDOWS /* windows.h is not included by Python.h so use void* instead of HANDLE */ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 747184415e8bc..afb6d183077a1 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -34,6 +34,7 @@ #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_import.h" // _PyImport_ReInitLock() +#include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS @@ -461,15 +462,41 @@ PyOS_AfterFork_Parent(void) void PyOS_AfterFork_Child(void) { + PyStatus status; _PyRuntimeState *runtime = &_PyRuntime; - _PyGILState_Reinit(runtime); - _PyEval_ReInitThreads(runtime); - _PyImport_ReInitLock(); + + status = _PyGILState_Reinit(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + status = _PyEval_ReInitThreads(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + status = _PyImport_ReInitLock(); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + _PySignal_AfterFork(); - _PyRuntimeState_ReInitThreads(runtime); - _PyInterpreterState_DeleteExceptMain(runtime); + + status = _PyRuntimeState_ReInitThreads(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } + + status = _PyInterpreterState_DeleteExceptMain(runtime); + if (_PyStatus_EXCEPTION(status)) { + goto fatal_error; + } run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0); + return; + +fatal_error: + Py_ExitStatusException(status); } static int diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 6d340a68634af..24dbd4255a6e4 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1796,14 +1796,17 @@ PyOS_InterruptOccurred(void) return 1; } + +#ifdef HAVE_FORK static void _clear_pending_signals(void) { - int i; - if (!_Py_atomic_load(&is_tripped)) + if (!_Py_atomic_load(&is_tripped)) { return; + } + _Py_atomic_store(&is_tripped, 0); - for (i = 1; i < NSIG; ++i) { + for (int i = 1; i < NSIG; ++i) { _Py_atomic_store_relaxed(&Handlers[i].tripped, 0); } } @@ -1816,6 +1819,8 @@ _PySignal_AfterFork(void) * the interpreter had an opportunity to call the handlers. issue9535. */ _clear_pending_signals(); } +#endif /* HAVE_FORK */ + int _PyOS_IsMainThread(void) diff --git a/Python/ceval.c b/Python/ceval.c index 01dd361e5035f..5edcfe354054a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -433,11 +433,9 @@ PyEval_ReleaseThread(PyThreadState *tstate) #ifdef HAVE_FORK /* This function is called from PyOS_AfterFork_Child to destroy all threads - * which are not running in the child process, and clear internal locks - * which might be held by those threads. - */ - -void + which are not running in the child process, and clear internal locks + which might be held by those threads. */ +PyStatus _PyEval_ReInitThreads(_PyRuntimeState *runtime) { PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); @@ -449,7 +447,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) struct _gil_runtime_state *gil = &runtime->ceval.gil; #endif if (!gil_created(gil)) { - return; + return _PyStatus_OK(); } recreate_gil(gil); @@ -457,11 +455,12 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) struct _pending_calls *pending = &tstate->interp->ceval.pending; if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - Py_FatalError("Can't initialize threads for pending calls"); + return _PyStatus_ERR("Can't reinitialize pending calls lock"); } /* Destroy all threads except the current one */ _PyThreadState_DeleteExcept(runtime, tstate); + return _PyStatus_OK(); } #endif diff --git a/Python/import.c b/Python/import.c index 0e2e7c370868f..35724fef37a6b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -148,7 +148,7 @@ _PyImportZip_Init(PyThreadState *tstate) in different threads to return with a partially loaded module. These calls are serialized by the global interpreter lock. */ -static PyThread_type_lock import_lock = 0; +static PyThread_type_lock import_lock = NULL; static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; static int import_lock_level = 0; @@ -171,7 +171,7 @@ _PyImport_AcquireLock(void) !PyThread_acquire_lock(import_lock, 0)) { PyThreadState *tstate = PyEval_SaveThread(); - PyThread_acquire_lock(import_lock, 1); + PyThread_acquire_lock(import_lock, WAIT_LOCK); PyEval_RestoreThread(tstate); } assert(import_lock_level == 0); @@ -197,19 +197,19 @@ _PyImport_ReleaseLock(void) } #ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to ensure that newly +/* This function is called from PyOS_AfterFork_Child() to ensure that newly created child processes do not share locks with the parent. We now acquire the import lock around fork() calls but on some platforms (Solaris 9 and earlier? see isue7242) that still left us with problems. */ - -void +PyStatus _PyImport_ReInitLock(void) { if (import_lock != NULL) { if (_PyThread_at_fork_reinit(&import_lock) < 0) { - _Py_FatalErrorFunc(__func__, "failed to create a new lock"); + return _PyStatus_ERR("failed to create a new lock"); } } + if (import_lock_level > 1) { /* Forked as a side effect of import */ unsigned long me = PyThread_get_thread_ident(); @@ -224,6 +224,7 @@ _PyImport_ReInitLock(void) import_lock_thread = PYTHREAD_INVALID_THREAD_ID; import_lock_level = 0; } + return _PyStatus_OK(); } #endif diff --git a/Python/pystate.c b/Python/pystate.c index f92c55e747169..72d8b36342517 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -124,10 +124,8 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) #ifdef HAVE_FORK /* This function is called from PyOS_AfterFork_Child to ensure that - * newly created child processes do not share locks with the parent. - */ - -void + newly created child processes do not share locks with the parent. */ +PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) { // This was initially set in _PyRuntimeState_Init(). @@ -138,23 +136,20 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - int interp_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); - int main_interp_id_mutex = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); - int xidregistry_mutex = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); + int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); + int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); + int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (interp_mutex < 0) { - Py_FatalError("Can't initialize lock for runtime interpreters"); - } - - if (main_interp_id_mutex < 0) { - Py_FatalError("Can't initialize ID lock for main interpreter"); - } + if (reinit_interp < 0 + || reinit_main_id < 0 + || reinit_xidregistry < 0) + { + return _PyStatus_ERR("Failed to reinitialize runtime locks"); - if (xidregistry_mutex < 0) { - Py_FatalError("Can't initialize lock for cross-interpreter data registry"); } + return _PyStatus_OK(); } #endif @@ -373,11 +368,12 @@ PyInterpreterState_Delete(PyInterpreterState *interp) } +#ifdef HAVE_FORK /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. */ -void +PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; @@ -385,7 +381,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); if (tstate != NULL && tstate->interp != interpreters->main) { - Py_FatalError("not main interpreter"); + return _PyStatus_ERR("not main interpreter"); } HEAD_LOCK(runtime); @@ -411,10 +407,12 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) HEAD_UNLOCK(runtime); if (interpreters->head == NULL) { - Py_FatalError("missing main interpreter"); + return _PyStatus_ERR("missing main interpreter"); } _PyThreadState_Swap(gilstate, tstate); + return _PyStatus_OK(); } +#endif PyInterpreterState * @@ -1259,11 +1257,12 @@ _PyGILState_Fini(PyThreadState *tstate) gilstate->autoInterpreterState = NULL; } +#ifdef HAVE_FORK /* Reset the TSS key - called by PyOS_AfterFork_Child(). * This should not be necessary, but some - buggy - pthread implementations * don't reset TSS upon fork(), see issue #10517. */ -void +PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime) { struct _gilstate_runtime_state *gilstate = &runtime->gilstate; @@ -1271,7 +1270,7 @@ _PyGILState_Reinit(_PyRuntimeState *runtime) PyThread_tss_delete(&gilstate->autoTSSkey); if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - Py_FatalError("Could not allocate TSS entry"); + return _PyStatus_NO_MEMORY(); } /* If the thread had an associated auto thread state, reassociate it with @@ -1279,9 +1278,11 @@ _PyGILState_Reinit(_PyRuntimeState *runtime) if (tstate && PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) { - Py_FatalError("Couldn't create autoTSSkey mapping"); + return _PyStatus_ERR("failed to set autoTSSkey"); } + return _PyStatus_OK(); } +#endif /* When a thread state is created for a thread by some mechanism other than PyGILState_Ensure, it's important that the GILState machinery knows about From webhook-mailer at python.org Tue Jun 2 11:14:01 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 15:14:01 -0000 Subject: [Python-checkins] bpo-40232: _PyImport_ReInitLock() can now safely use its lock (GH-20597) Message-ID: https://github.com/python/cpython/commit/45b34a04a577aa49fa4825421758c3e8eaa1625d commit: 45b34a04a577aa49fa4825421758c3e8eaa1625d branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T17:13:49+02:00 summary: bpo-40232: _PyImport_ReInitLock() can now safely use its lock (GH-20597) Since _PyImport_ReInitLock() now calls _PyThread_at_fork_reinit() on the import lock, the lock is now in a known state: unlocked. It became safe to acquire it after fork. files: M Python/import.c diff --git a/Python/import.c b/Python/import.c index 35724fef37a6b..505688400ef3e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -213,11 +213,7 @@ _PyImport_ReInitLock(void) if (import_lock_level > 1) { /* Forked as a side effect of import */ unsigned long me = PyThread_get_thread_ident(); - /* The following could fail if the lock is already held, but forking as - a side-effect of an import is a) rare, b) nuts, and c) difficult to - do thanks to the lock only being held when doing individual module - locks per import. */ - PyThread_acquire_lock(import_lock, NOWAIT_LOCK); + PyThread_acquire_lock(import_lock, WAIT_LOCK); import_lock_thread = me; import_lock_level--; } else { From webhook-mailer at python.org Tue Jun 2 12:45:03 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 02 Jun 2020 16:45:03 -0000 Subject: [Python-checkins] PyOS_AfterFork_Child() pass tstate to _PyEval_ReInitThreads() (GH-20598) Message-ID: https://github.com/python/cpython/commit/317bab0bf61e4cbab37c81baf185d8b57ca62a6b commit: 317bab0bf61e4cbab37c81baf185d8b57ca62a6b branch: master author: Victor Stinner committer: GitHub date: 2020-06-02T18:44:54+02:00 summary: PyOS_AfterFork_Child() pass tstate to _PyEval_ReInitThreads() (GH-20598) files: M Include/internal/pycore_ceval.h M Modules/posixmodule.c M Python/ceval.c diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 2da0154525b1c..aafb533b57d5f 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -25,7 +25,7 @@ PyAPI_FUNC(int) _PyEval_AddPendingCall( void *arg); PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyThreadState *tstate); #ifdef HAVE_FORK -extern PyStatus _PyEval_ReInitThreads(struct pyruntimestate *runtime); +extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( PyThreadState *tstate, diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index afb6d183077a1..79779bfdeafd3 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -470,7 +470,10 @@ PyOS_AfterFork_Child(void) goto fatal_error; } - status = _PyEval_ReInitThreads(runtime); + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + + status = _PyEval_ReInitThreads(tstate); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } @@ -491,8 +494,9 @@ PyOS_AfterFork_Child(void) if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } + assert(_PyThreadState_GET() == tstate); - run_at_forkers(_PyInterpreterState_GET()->after_forkers_child, 0); + run_at_forkers(tstate->interp->after_forkers_child, 0); return; fatal_error: diff --git a/Python/ceval.c b/Python/ceval.c index 5edcfe354054a..9ab8329d6d8e7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -436,10 +436,9 @@ PyEval_ReleaseThread(PyThreadState *tstate) which are not running in the child process, and clear internal locks which might be held by those threads. */ PyStatus -_PyEval_ReInitThreads(_PyRuntimeState *runtime) +_PyEval_ReInitThreads(PyThreadState *tstate) { - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); + _PyRuntimeState *runtime = tstate->interp->runtime; #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS struct _gil_runtime_state *gil = &tstate->interp->ceval.gil; From webhook-mailer at python.org Wed Jun 3 08:36:56 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 03 Jun 2020 12:36:56 -0000 Subject: [Python-checkins] bpo-32604: Fix reference leak in select module (GH-20600) Message-ID: https://github.com/python/cpython/commit/18a90248fdd92b27098cc4db773686a2d10a4d24 commit: 18a90248fdd92b27098cc4db773686a2d10a4d24 branch: master author: Victor Stinner committer: GitHub date: 2020-06-03T14:36:46+02:00 summary: bpo-32604: Fix reference leak in select module (GH-20600) Fix reference leak in PyInit_select() of the select module: remove Py_INCREF(poll_Type). files: A Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst M Modules/selectmodule.c diff --git a/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst b/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst new file mode 100644 index 0000000000000..6375276602e4a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-02-23-49-07.bpo-32604.ZN4V4l.rst @@ -0,0 +1,2 @@ +Fix reference leak in the :mod:`select` module when the the module is +imported in a subinterpreter. diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 04e0067eec218..adf014fac43d4 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2482,7 +2482,6 @@ PyInit_select(void) if (poll_Type == NULL) return NULL; get_select_state(m)->poll_Type = (PyTypeObject *)poll_Type; - Py_INCREF(poll_Type); PyModule_AddIntMacro(m, POLLIN); PyModule_AddIntMacro(m, POLLPRI); @@ -2518,7 +2517,6 @@ PyInit_select(void) if (devpoll_Type == NULL) return NULL; get_select_state(m)->devpoll_Type = (PyTypeObject *)devpoll_Type; - Py_INCREF(devpoll_Type); #endif #ifdef HAVE_EPOLL From webhook-mailer at python.org Wed Jun 3 08:40:04 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 03 Jun 2020 12:40:04 -0000 Subject: [Python-checkins] bpo-40826: Add _PyOS_InterruptOccurred(tstate) function (GH-20599) Message-ID: https://github.com/python/cpython/commit/fa7ab6aa0f9a4f695e5525db5a113cd21fa93787 commit: fa7ab6aa0f9a4f695e5525db5a113cd21fa93787 branch: master author: Victor Stinner committer: GitHub date: 2020-06-03T14:39:59+02:00 summary: bpo-40826: Add _PyOS_InterruptOccurred(tstate) function (GH-20599) my_fgets() now calls _PyOS_InterruptOccurred(tstate) to check for pending signals, rather calling PyOS_InterruptOccurred(). my_fgets() is called with the GIL released, whereas PyOS_InterruptOccurred() must be called with the GIL held. test_repl: use text=True and avoid SuppressCrashReport in test_multiline_string_parsing(). Fix my_fgets() on Windows: fgets(fp) does crash if fileno(fp) is closed. files: M Include/internal/pycore_pystate.h M Lib/test/test_repl.py M Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst M Modules/signalmodule.c M Parser/myreadline.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 423c8113d7ac0..0cd5550cfda5c 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -144,6 +144,9 @@ PyAPI_FUNC(int) _PyState_AddModule( PyObject* module, struct PyModuleDef* def); + +PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 71f192f90d9a1..563f188706b93 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -29,7 +29,9 @@ def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): # test.support.script_helper. env = kw.setdefault('env', dict(os.environ)) env['TERM'] = 'vt100' - return subprocess.Popen(cmd_line, executable=sys.executable, + return subprocess.Popen(cmd_line, + executable=sys.executable, + text=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, **kw) @@ -49,12 +51,11 @@ def test_no_memory(self): sys.exit(0) """ user_input = dedent(user_input) - user_input = user_input.encode() p = spawn_repl() with SuppressCrashReport(): p.stdin.write(user_input) output = kill_python(p) - self.assertIn(b'After the exception.', output) + self.assertIn('After the exception.', output) # Exit code 120: Py_FinalizeEx() failed to flush stdout and stderr. self.assertIn(p.returncode, (1, 120)) @@ -86,13 +87,22 @@ def test_multiline_string_parsing(self): """ ''' user_input = dedent(user_input) - user_input = user_input.encode() p = spawn_repl() - with SuppressCrashReport(): - p.stdin.write(user_input) + p.stdin.write(user_input) output = kill_python(p) self.assertEqual(p.returncode, 0) + def test_close_stdin(self): + user_input = dedent(''' + import os + print("before close") + os.close(0) + ''') + process = spawn_repl() + output = process.communicate(user_input)[0] + self.assertEqual(process.returncode, 0) + self.assertIn('before close', output) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst index f79f20d21d49c..a03ed180eb952 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst @@ -1 +1,2 @@ -Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception. +Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception +and pass the Python thread state when checking if there is a pending signal. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 24dbd4255a6e4..ef3536a210b04 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1779,10 +1779,11 @@ PyOS_FiniInterrupts(void) finisignal(); } + +// The caller doesn't have to hold the GIL int -PyOS_InterruptOccurred(void) +_PyOS_InterruptOccurred(PyThreadState *tstate) { - PyThreadState *tstate = _PyThreadState_GET(); _Py_EnsureTstateNotNULL(tstate); if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; @@ -1797,6 +1798,15 @@ PyOS_InterruptOccurred(void) } +// The caller must to hold the GIL +int +PyOS_InterruptOccurred(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyOS_InterruptOccurred(tstate); +} + + #ifdef HAVE_FORK static void _clear_pending_signals(void) diff --git a/Parser/myreadline.c b/Parser/myreadline.c index d2787f0d345cf..2dd362321aaf3 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -24,14 +24,23 @@ static PyThread_type_lock _PyOS_ReadlineLock = NULL; int (*PyOS_InputHook)(void) = NULL; /* This function restarts a fgets() after an EINTR error occurred - except if PyOS_InterruptOccurred() returns true. */ + except if _PyOS_InterruptOccurred() returns true. */ static int my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) { #ifdef MS_WINDOWS - HANDLE hInterruptEvent; + HANDLE handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fileno(fp)); + _Py_END_SUPPRESS_IPH + + /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */ + if (handle == INVALID_HANDLE_VALUE) { + return -1; /* EOF */ + } #endif + while (1) { if (PyOS_InputHook != NULL) { (void)(PyOS_InputHook)(); @@ -60,7 +69,7 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) through to check for EOF. */ if (GetLastError()==ERROR_OPERATION_ABORTED) { - hInterruptEvent = _PyOS_SigintEvent(); + HANDLE hInterruptEvent = _PyOS_SigintEvent(); switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) { case WAIT_OBJECT_0: ResetEvent(hInterruptEvent); @@ -90,7 +99,7 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) } #endif - if (PyOS_InterruptOccurred()) { + if (_PyOS_InterruptOccurred(tstate)) { return 1; /* Interrupt */ } return -2; /* Error */ From webhook-mailer at python.org Wed Jun 3 08:42:38 2020 From: webhook-mailer at python.org (Jeremy Attali) Date: Wed, 03 Jun 2020 12:42:38 -0000 Subject: [Python-checkins] bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Message-ID: https://github.com/python/cpython/commit/c822efeda9a0afe87cf3429724732fc8e19a01fb commit: c822efeda9a0afe87cf3429724732fc8e19a01fb branch: master author: Jeremy Attali committer: GitHub date: 2020-06-03T05:42:33-07:00 summary: bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Would be nice to backport to python 3.7+. I don't think it's worth the hassle to backport this all the way down to 3.10. But I'll let the maintainers decide. This is hard to test because the test setup already includes this [environment variable](https://github.com/python/cpython/blob/master/Lib/test/pythoninfo.py#L292) Let me know if something doesn't match the PR guidelines. This is my first PR in the python source code. files: A Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst M Lib/webbrowser.py diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 9c73bcfb44ae8..3dcf66b659825 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -545,7 +545,7 @@ def register_standard_browsers(): register(browser, None, BackgroundBrowser(browser)) else: # Prefer X browsers if present - if os.environ.get("DISPLAY"): + if os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"): try: cmd = "xdg-settings get default-web-browser".split() raw_result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) diff --git a/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst new file mode 100644 index 0000000000000..4bebb311b4d54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst @@ -0,0 +1,3 @@ +:mod:`webbrowser` now properly finds the default browser in pure Wayland +systems by checking the WAYLAND_DISPLAY environment variable. Patch +contributed by J?r?my Attali. From webhook-mailer at python.org Wed Jun 3 09:01:28 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 03 Jun 2020 13:01:28 -0000 Subject: [Python-checkins] bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Message-ID: https://github.com/python/cpython/commit/911c35d5d334b8c148202f2a7a32b511958032fc commit: 911c35d5d334b8c148202f2a7a32b511958032fc branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-03T06:01:23-07:00 summary: bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Would be nice to backport to python 3.7+. I don't think it's worth the hassle to backport this all the way down to 3.10. But I'll let the maintainers decide. This is hard to test because the test setup already includes this [environment variable](https://github.com/python/cpython/blob/master/Lib/test/pythoninfo.pyGH-L292) Let me know if something doesn't match the PR guidelines. This is my first PR in the python source code. (cherry picked from commit c822efeda9a0afe87cf3429724732fc8e19a01fb) Co-authored-by: Jeremy Attali files: A Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst M Lib/webbrowser.py diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 34b86a505c246..b04ec7b65ae3b 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -540,7 +540,7 @@ def register_standard_browsers(): register(browser, None, BackgroundBrowser(browser)) else: # Prefer X browsers if present - if os.environ.get("DISPLAY"): + if os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"): try: cmd = "xdg-settings get default-web-browser".split() raw_result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) diff --git a/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst new file mode 100644 index 0000000000000..4bebb311b4d54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst @@ -0,0 +1,3 @@ +:mod:`webbrowser` now properly finds the default browser in pure Wayland +systems by checking the WAYLAND_DISPLAY environment variable. Patch +contributed by J?r?my Attali. From webhook-mailer at python.org Wed Jun 3 09:02:37 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 03 Jun 2020 13:02:37 -0000 Subject: [Python-checkins] bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Message-ID: https://github.com/python/cpython/commit/5b8787ef191864cd2313015959bcc3e10711aaff commit: 5b8787ef191864cd2313015959bcc3e10711aaff branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-03T06:02:33-07:00 summary: bpo-40767: Allow pure Wayland to get default XDG web browser (GH-20382) Would be nice to backport to python 3.7+. I don't think it's worth the hassle to backport this all the way down to 3.10. But I'll let the maintainers decide. This is hard to test because the test setup already includes this [environment variable](https://github.com/python/cpython/blob/master/Lib/test/pythoninfo.pyGH-L292) Let me know if something doesn't match the PR guidelines. This is my first PR in the python source code. (cherry picked from commit c822efeda9a0afe87cf3429724732fc8e19a01fb) Co-authored-by: Jeremy Attali files: A Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst M Lib/webbrowser.py diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 9c73bcfb44ae8..3dcf66b659825 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -545,7 +545,7 @@ def register_standard_browsers(): register(browser, None, BackgroundBrowser(browser)) else: # Prefer X browsers if present - if os.environ.get("DISPLAY"): + if os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"): try: cmd = "xdg-settings get default-web-browser".split() raw_result = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) diff --git a/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst new file mode 100644 index 0000000000000..4bebb311b4d54 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-27-21-27-01.bpo-40767.L5MnVV.rst @@ -0,0 +1,3 @@ +:mod:`webbrowser` now properly finds the default browser in pure Wayland +systems by checking the WAYLAND_DISPLAY environment variable. Patch +contributed by J?r?my Attali. From webhook-mailer at python.org Wed Jun 3 09:19:50 2020 From: webhook-mailer at python.org (Alex Povel) Date: Wed, 03 Jun 2020 13:19:50 -0000 Subject: [Python-checkins] bpo-40471: Fix grammar typo in 'issubclass' docstring (GH-19847) Message-ID: https://github.com/python/cpython/commit/df773f8c5454acebe08c31e7308597fa5a8bf5df commit: df773f8c5454acebe08c31e7308597fa5a8bf5df branch: master author: Alex Povel <48824213+alexpovel at users.noreply.github.com> committer: GitHub date: 2020-06-03T06:19:45-07:00 summary: bpo-40471: Fix grammar typo in 'issubclass' docstring (GH-19847) Just a brief grammar fix. See also <>. files: M Python/bltinmodule.c M Python/clinic/bltinmodule.c.h diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 199b09c4d8c41..65f9528084654 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2494,17 +2494,17 @@ issubclass as builtin_issubclass class_or_tuple: object / -Return whether 'cls' is a derived from another class or is the same class. +Return whether 'cls' is derived from another class or is the same class. A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) -or ...`` etc. +or ...``. [clinic start generated code]*/ static PyObject * builtin_issubclass_impl(PyObject *module, PyObject *cls, PyObject *class_or_tuple) -/*[clinic end generated code: output=358412410cd7a250 input=af5f35e9ceaddaf6]*/ +/*[clinic end generated code: output=358412410cd7a250 input=a24b9f3d58c370d6]*/ { int retval; diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 377afded9f8c5..bc3b518792811 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -800,11 +800,11 @@ PyDoc_STRVAR(builtin_issubclass__doc__, "issubclass($module, cls, class_or_tuple, /)\n" "--\n" "\n" -"Return whether \'cls\' is a derived from another class or is the same class.\n" +"Return whether \'cls\' is derived from another class or is the same class.\n" "\n" "A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n" "check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n" -"or ...`` etc."); +"or ...``."); #define BUILTIN_ISSUBCLASS_METHODDEF \ {"issubclass", (PyCFunction)(void(*)(void))builtin_issubclass, METH_FASTCALL, builtin_issubclass__doc__}, @@ -830,4 +830,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=780fd9712ec6a6db input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e2fcf0201790367c input=a9049054013a1b77]*/ From webhook-mailer at python.org Wed Jun 3 10:18:23 2020 From: webhook-mailer at python.org (aboddie) Date: Wed, 03 Jun 2020 14:18:23 -0000 Subject: [Python-checkins] Update error message in _zoneinfo.py to use f-string (GH-20577) Message-ID: https://github.com/python/cpython/commit/5b9fbbabacca0378755fd9cadc4a7cc01a71eaef commit: 5b9fbbabacca0378755fd9cadc4a7cc01a71eaef branch: master author: aboddie <64019758+aboddie at users.noreply.github.com> committer: GitHub date: 2020-06-03T07:18:19-07:00 summary: Update error message in _zoneinfo.py to use f-string (GH-20577) Inline with the rest of the file, updated error message to use f-string. files: M Lib/zoneinfo/_zoneinfo.py diff --git a/Lib/zoneinfo/_zoneinfo.py b/Lib/zoneinfo/_zoneinfo.py index 7b1718a0676e1..9810637d3ef65 100644 --- a/Lib/zoneinfo/_zoneinfo.py +++ b/Lib/zoneinfo/_zoneinfo.py @@ -742,7 +742,7 @@ def _parse_tz_delta(tz_delta): if not -86400 < total < 86400: raise ValueError( - "Offset must be strictly between -24h and +24h:" + tz_delta + f"Offset must be strictly between -24h and +24h: {tz_delta}" ) # Yes, +5 maps to an offset of -5h From webhook-mailer at python.org Wed Jun 3 11:43:54 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Wed, 03 Jun 2020 15:43:54 -0000 Subject: [Python-checkins] Remove unused ReaderObject_Check macro (#20614) Message-ID: https://github.com/python/cpython/commit/586be6f3ff68ab4034e555f1434a4427e129ad0b commit: 586be6f3ff68ab4034e555f1434a4427e129ad0b branch: master author: Dong-hee Na committer: GitHub date: 2020-06-04T00:43:46+09:00 summary: Remove unused ReaderObject_Check macro (#20614) files: M Modules/_csv.c diff --git a/Modules/_csv.c b/Modules/_csv.c index 3a52632ccfd45..f33733aaf850d 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -112,8 +112,6 @@ typedef struct { static PyTypeObject Reader_Type; -#define ReaderObject_Check(v) Py_IS_TYPE(v, &Reader_Type) - typedef struct { PyObject_HEAD From webhook-mailer at python.org Wed Jun 3 12:28:27 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 03 Jun 2020 16:28:27 -0000 Subject: [Python-checkins] [3.9] bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20613) (GH-20616) Message-ID: https://github.com/python/cpython/commit/6f7346bb3983cd7a6aa97eeeafffb3cecd5292b8 commit: 6f7346bb3983cd7a6aa97eeeafffb3cecd5292b8 branch: 3.8 author: Victor Stinner committer: GitHub date: 2020-06-03T18:28:18+02:00 summary: [3.9] bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20613) (GH-20616) * bpo-40826: Fix GIL usage in PyOS_Readline() (GH-20579) Fix GIL usage in PyOS_Readline(): lock the GIL to set an exception. Pass tstate to my_fgets() and _PyOS_WindowsConsoleReadline(). Cleanup these functions. (cherry picked from commit c353764fd564e401cf47a5d9efab18c72c60014e) * bpo-40826: Add _PyOS_InterruptOccurred(tstate) function (GH-20599) my_fgets() now calls _PyOS_InterruptOccurred(tstate) to check for pending signals, rather calling PyOS_InterruptOccurred(). my_fgets() is called with the GIL released, whereas PyOS_InterruptOccurred() must be called with the GIL held. test_repl: use text=True and avoid SuppressCrashReport in test_multiline_string_parsing(). Fix my_fgets() on Windows: fgets(fp) does crash if fileno(fp) is closed. (cherry picked from commit fa7ab6aa0f9a4f695e5525db5a113cd21fa93787) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst M Include/internal/pycore_pystate.h M Lib/test/test_repl.py M Modules/signalmodule.c M Parser/myreadline.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index f90e7e1ab78e3..96d5e31d83a6e 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -317,6 +317,9 @@ PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); + +PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py index 71f192f90d9a1..563f188706b93 100644 --- a/Lib/test/test_repl.py +++ b/Lib/test/test_repl.py @@ -29,7 +29,9 @@ def spawn_repl(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): # test.support.script_helper. env = kw.setdefault('env', dict(os.environ)) env['TERM'] = 'vt100' - return subprocess.Popen(cmd_line, executable=sys.executable, + return subprocess.Popen(cmd_line, + executable=sys.executable, + text=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, **kw) @@ -49,12 +51,11 @@ def test_no_memory(self): sys.exit(0) """ user_input = dedent(user_input) - user_input = user_input.encode() p = spawn_repl() with SuppressCrashReport(): p.stdin.write(user_input) output = kill_python(p) - self.assertIn(b'After the exception.', output) + self.assertIn('After the exception.', output) # Exit code 120: Py_FinalizeEx() failed to flush stdout and stderr. self.assertIn(p.returncode, (1, 120)) @@ -86,13 +87,22 @@ def test_multiline_string_parsing(self): """ ''' user_input = dedent(user_input) - user_input = user_input.encode() p = spawn_repl() - with SuppressCrashReport(): - p.stdin.write(user_input) + p.stdin.write(user_input) output = kill_python(p) self.assertEqual(p.returncode, 0) + def test_close_stdin(self): + user_input = dedent(''' + import os + print("before close") + os.close(0) + ''') + process = spawn_repl() + output = process.communicate(user_input)[0] + self.assertEqual(process.returncode, 0) + self.assertIn('before close', output) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst new file mode 100644 index 0000000000000..a03ed180eb952 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-01-20-31-07.bpo-40826.XCI4M2.rst @@ -0,0 +1,2 @@ +Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception +and pass the Python thread state when checking if there is a pending signal. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 0c9a2671fe19b..119fc355ff1fd 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -187,14 +187,20 @@ itimer_retval(struct itimerval *iv) #endif static int -is_main(_PyRuntimeState *runtime) +is_main_interp(_PyRuntimeState *runtime, PyInterpreterState *interp) { unsigned long thread = PyThread_get_thread_ident(); - PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; return (thread == runtime->main_thread && interp == runtime->interpreters.main); } +static int +is_main(_PyRuntimeState *runtime) +{ + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + return is_main_interp(runtime, interp); +} + static PyObject * signal_default_int_handler(PyObject *self, PyObject *args) { @@ -1726,12 +1732,14 @@ PyOS_FiniInterrupts(void) finisignal(); } + +// The caller doesn't have to hold the GIL int -PyOS_InterruptOccurred(void) +_PyOS_InterruptOccurred(PyThreadState *tstate) { if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) { _PyRuntimeState *runtime = &_PyRuntime; - if (!is_main(runtime)) { + if (!is_main_interp(runtime, tstate->interp)) { return 0; } _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0); @@ -1740,6 +1748,16 @@ PyOS_InterruptOccurred(void) return 0; } + +// The caller must to hold the GIL +int +PyOS_InterruptOccurred(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyOS_InterruptOccurred(tstate); +} + + static void _clear_pending_signals(void) { diff --git a/Parser/myreadline.c b/Parser/myreadline.c index 43e5583b8bcc4..d7ed357faa383 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -25,25 +25,36 @@ static PyThread_type_lock _PyOS_ReadlineLock = NULL; int (*PyOS_InputHook)(void) = NULL; /* This function restarts a fgets() after an EINTR error occurred - except if PyOS_InterruptOccurred() returns true. */ + except if _PyOS_InterruptOccurred() returns true. */ static int -my_fgets(char *buf, int len, FILE *fp) +my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) { #ifdef MS_WINDOWS - HANDLE hInterruptEvent; + HANDLE handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (HANDLE)_get_osfhandle(fileno(fp)); + _Py_END_SUPPRESS_IPH + + /* bpo-40826: fgets(fp) does crash if fileno(fp) is closed */ + if (handle == INVALID_HANDLE_VALUE) { + return -1; /* EOF */ + } #endif - char *p; - int err; + while (1) { - if (PyOS_InputHook != NULL) + if (PyOS_InputHook != NULL) { (void)(PyOS_InputHook)(); + } + errno = 0; clearerr(fp); - p = fgets(buf, len, fp); - if (p != NULL) + char *p = fgets(buf, len, fp); + if (p != NULL) { return 0; /* No error */ - err = errno; + } + int err = errno; + #ifdef MS_WINDOWS /* Ctrl-C anywhere on the line or Ctrl-Z if the only character on a line will set ERROR_OPERATION_ABORTED. Under normal @@ -59,7 +70,7 @@ my_fgets(char *buf, int len, FILE *fp) through to check for EOF. */ if (GetLastError()==ERROR_OPERATION_ABORTED) { - hInterruptEvent = _PyOS_SigintEvent(); + HANDLE hInterruptEvent = _PyOS_SigintEvent(); switch (WaitForSingleObjectEx(hInterruptEvent, 10, FALSE)) { case WAIT_OBJECT_0: ResetEvent(hInterruptEvent); @@ -69,23 +80,27 @@ my_fgets(char *buf, int len, FILE *fp) } } #endif /* MS_WINDOWS */ + if (feof(fp)) { clearerr(fp); return -1; /* EOF */ } + #ifdef EINTR if (err == EINTR) { - int s; - PyEval_RestoreThread(_PyOS_ReadlineTState); - s = PyErr_CheckSignals(); + PyEval_RestoreThread(tstate); + int s = PyErr_CheckSignals(); PyEval_SaveThread(); - if (s < 0) - return 1; - /* try again */ + + if (s < 0) { + return 1; + } + /* try again */ continue; } #endif - if (PyOS_InterruptOccurred()) { + + if (_PyOS_InterruptOccurred(tstate)) { return 1; /* Interrupt */ } return -2; /* Error */ @@ -99,7 +114,7 @@ my_fgets(char *buf, int len, FILE *fp) extern char _get_console_type(HANDLE handle); char * -_PyOS_WindowsConsoleReadline(HANDLE hStdIn) +_PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) { static wchar_t wbuf_local[1024 * 16]; const DWORD chunk_size = 1024; @@ -134,11 +149,12 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) == WAIT_OBJECT_0) { ResetEvent(hInterruptEvent); - PyEval_RestoreThread(_PyOS_ReadlineTState); + PyEval_RestoreThread(tstate); s = PyErr_CheckSignals(); PyEval_SaveThread(); - if (s < 0) + if (s < 0) { goto exit; + } } break; } @@ -151,17 +167,22 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (wbuf == wbuf_local) { wbuf[total_read] = '\0'; wbuf = (wchar_t*)PyMem_RawMalloc(wbuflen * sizeof(wchar_t)); - if (wbuf) + if (wbuf) { wcscpy_s(wbuf, wbuflen, wbuf_local); + } else { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } } else { wchar_t *tmp = PyMem_RawRealloc(wbuf, wbuflen * sizeof(wchar_t)); if (tmp == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } wbuf = tmp; @@ -170,33 +191,45 @@ _PyOS_WindowsConsoleReadline(HANDLE hStdIn) if (wbuf[0] == '\x1a') { buf = PyMem_RawMalloc(1); - if (buf) + if (buf) { buf[0] = '\0'; + } else { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); } goto exit; } - u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, NULL, 0, NULL, NULL); + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + NULL, 0, + NULL, NULL); buf = PyMem_RawMalloc(u8len + 1); if (buf == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); goto exit; } - u8len = WideCharToMultiByte(CP_UTF8, 0, wbuf, total_read, buf, u8len, NULL, NULL); + + u8len = WideCharToMultiByte(CP_UTF8, 0, + wbuf, total_read, + buf, u8len, + NULL, NULL); buf[u8len] = '\0'; exit: - if (wbuf != wbuf_local) + if (wbuf != wbuf_local) { PyMem_RawFree(wbuf); + } if (err) { - PyEval_RestoreThread(_PyOS_ReadlineTState); + PyEval_RestoreThread(tstate); PyErr_SetFromWindowsErr(err); PyEval_SaveThread(); } - return buf; } @@ -210,6 +243,8 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { size_t n; char *p, *pr; + PyThreadState *tstate = _PyOS_ReadlineTState; + assert(tstate != NULL); #ifdef MS_WINDOWS if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { @@ -231,7 +266,9 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (wlen) { wbuf = PyMem_RawMalloc(wlen * sizeof(wchar_t)); if (wbuf == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } wlen = MultiByteToWideChar(CP_UTF8, 0, prompt, -1, @@ -250,7 +287,7 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) } } clearerr(sys_stdin); - return _PyOS_WindowsConsoleReadline(hStdIn); + return _PyOS_WindowsConsoleReadline(tstate, hStdIn); } } #endif @@ -258,16 +295,19 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) n = 100; p = (char *)PyMem_RawMalloc(n); if (p == NULL) { + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } fflush(sys_stdout); - if (prompt) + if (prompt) { fprintf(stderr, "%s", prompt); + } fflush(stderr); - switch (my_fgets(p, (int)n, sys_stdin)) { + switch (my_fgets(tstate, p, (int)n, sys_stdin)) { case 0: /* Normal case */ break; case 1: /* Interrupt */ @@ -279,29 +319,40 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) *p = '\0'; break; } + n = strlen(p); while (n > 0 && p[n-1] != '\n') { size_t incr = n+2; if (incr > INT_MAX) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_SetString(PyExc_OverflowError, "input line too long"); + PyEval_SaveThread(); return NULL; } + pr = (char *)PyMem_RawRealloc(p, n + incr); if (pr == NULL) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } p = pr; - if (my_fgets(p+n, (int)incr, sys_stdin) != 0) + + if (my_fgets(tstate, p+n, (int)incr, sys_stdin) != 0) { break; + } n += strlen(p+n); } + pr = (char *)PyMem_RawRealloc(p, n+1); if (pr == NULL) { PyMem_RawFree(p); + PyEval_RestoreThread(tstate); PyErr_NoMemory(); + PyEval_SaveThread(); return NULL; } return pr; @@ -324,7 +375,8 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) char *rv, *res; size_t len; - if (_PyOS_ReadlineTState == _PyThreadState_GET()) { + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyOS_ReadlineTState == tstate) { PyErr_SetString(PyExc_RuntimeError, "can't re-enter readline"); return NULL; @@ -343,7 +395,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) } } - _PyOS_ReadlineTState = _PyThreadState_GET(); + _PyOS_ReadlineTState = tstate; Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(_PyOS_ReadlineLock, 1); From webhook-mailer at python.org Thu Jun 4 01:19:40 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Thu, 04 Jun 2020 05:19:40 -0000 Subject: [Python-checkins] Fix MSVC warning in frameobject.c (GH-20590) Message-ID: https://github.com/python/cpython/commit/6e23a9c82b7fd2366003b9191cd93a9683b9d80c commit: 6e23a9c82b7fd2366003b9191cd93a9683b9d80c branch: master author: Ammar Askar committer: GitHub date: 2020-06-04T06:19:23+01:00 summary: Fix MSVC warning in frameobject.c (GH-20590) files: M Objects/frameobject.c diff --git a/Objects/frameobject.c b/Objects/frameobject.c index af32276c98b24..b6d073bd456d0 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -397,7 +397,9 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } - int len = PyBytes_GET_SIZE(f->f_code->co_code)/sizeof(_Py_CODEUNIT); + int len = Py_SAFE_DOWNCAST( + PyBytes_GET_SIZE(f->f_code->co_code)/sizeof(_Py_CODEUNIT), + Py_ssize_t, int); int *lines = marklines(f->f_code, len); if (lines == NULL) { return -1; From webhook-mailer at python.org Thu Jun 4 08:23:52 2020 From: webhook-mailer at python.org (Mark Shannon) Date: Thu, 04 Jun 2020 12:23:52 -0000 Subject: [Python-checkins] Don't raise an exception on normal return from generator. (GH-19473) Message-ID: https://github.com/python/cpython/commit/50a48dad5579d67d7cae350f6ad5ae5c33f56abb commit: 50a48dad5579d67d7cae350f6ad5ae5c33f56abb branch: master author: Mark Shannon committer: GitHub date: 2020-06-04T13:23:35+01:00 summary: Don't raise an exception on normal return from generator. (GH-19473) files: A Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst M Objects/genobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst new file mode 100644 index 0000000000000..a13a8e8822683 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-04-11-13-07-49.bpo-4022.Ctpn_F.rst @@ -0,0 +1 @@ +Improve performance of generators by not raising internal StopIteration. diff --git a/Objects/genobject.c b/Objects/genobject.c index 09efbab69a7d3..1393f42533a59 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -231,7 +231,8 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) if (PyAsyncGen_CheckExact(gen)) { PyErr_SetNone(PyExc_StopAsyncIteration); } - else { + else if (arg) { + /* Set exception if not called by gen_iternext() */ PyErr_SetNone(PyExc_StopIteration); } } From webhook-mailer at python.org Thu Jun 4 08:48:25 2020 From: webhook-mailer at python.org (Christian Heimes) Date: Thu, 04 Jun 2020 12:48:25 -0000 Subject: [Python-checkins] bpo-17258: Add requires_hashdigest to multiprocessing tests (GH-20412) Message-ID: https://github.com/python/cpython/commit/b022e5cffbd3ff51ae361cf80f2a3b660be8b1ee commit: b022e5cffbd3ff51ae361cf80f2a3b660be8b1ee branch: master author: Christian Heimes committer: GitHub date: 2020-06-04T05:48:17-07:00 summary: bpo-17258: Add requires_hashdigest to multiprocessing tests (GH-20412) Skip some :mod:`multiprocessing` tests when MD5 hash digest is blocked. Signed-off-by: Christian Heimes files: A Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst M Lib/test/_test_multiprocessing.py M Lib/test/test_concurrent_futures.py diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index bbba2b45e5f03..d01a6680e409c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -26,6 +26,7 @@ import test.support import test.support.script_helper from test import support +from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper @@ -2954,6 +2955,8 @@ def test_remote(self): # Make queue finalizer run before the server is stopped del queue + + at hashlib_helper.requires_hashdigest('md5') class _TestManagerRestart(BaseTestCase): @classmethod @@ -3438,6 +3441,7 @@ def test_dont_merge(self): # @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") + at hashlib_helper.requires_hashdigest('md5') class _TestPicklingConnections(BaseTestCase): ALLOWED_TYPES = ('processes',) @@ -3740,6 +3744,7 @@ def test_copy(self): @unittest.skipUnless(HAS_SHMEM, "requires multiprocessing.shared_memory") + at hashlib_helper.requires_hashdigest('md5') class _TestSharedMemory(BaseTestCase): ALLOWED_TYPES = ('processes',) @@ -4415,6 +4420,7 @@ def test_invalid_handles(self): + at hashlib_helper.requires_hashdigest('md5') class OtherTest(unittest.TestCase): # TODO: add more tests for deliver/answer challenge. def test_deliver_challenge_auth_failure(self): @@ -4451,6 +4457,7 @@ def send_bytes(self, data): def initializer(ns): ns.test += 1 + at hashlib_helper.requires_hashdigest('md5') class TestInitializers(unittest.TestCase): def setUp(self): self.mgr = multiprocessing.Manager() @@ -5305,6 +5312,7 @@ def is_alive(self): any(process.is_alive() for process in forked_processes)) + at hashlib_helper.requires_hashdigest('md5') class TestSyncManagerTypes(unittest.TestCase): """Test all the types which can be shared between a parent and a child process by using a manager which acts as an intermediary @@ -5699,6 +5707,8 @@ def install_tests_in_module_dict(remote_globs, start_method): Mixin = local_globs[type_.capitalize() + 'Mixin'] class Temp(base, Mixin, unittest.TestCase): pass + if type_ == 'manager': + Temp = hashlib_helper.requires_hashdigest('md5')(Temp) Temp.__name__ = Temp.__qualname__ = newname Temp.__module__ = __module__ remote_globs[newname] = Temp diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 3b74949a5f61d..0ed75e6098a80 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -6,6 +6,7 @@ # Skip tests if sem_open implementation is broken. support.import_module('multiprocessing.synchronize') +from test.support import hashlib_helper from test.support.script_helper import assert_python_ok import contextlib @@ -953,6 +954,7 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) + @hashlib_helper.requires_hashdigest('md5') def test_ressources_gced_in_workers(self): # Ensure that argument for a job are correctly gc-ed after the job # is finished diff --git a/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst b/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst new file mode 100644 index 0000000000000..0a4b329b802e3 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2020-05-26-07-53-31.bpo-17258.X_IKTQ.rst @@ -0,0 +1 @@ +Skip some :mod:`multiprocessing` tests when MD5 hash digest is blocked. From webhook-mailer at python.org Thu Jun 4 09:19:10 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 13:19:10 -0000 Subject: [Python-checkins] bpo-40679: Fix _PyEval_EvalCode() crash if qualname is NULL (GH-20615) Message-ID: https://github.com/python/cpython/commit/232dda6cbc10860328a83517a6e3ea238ff4147f commit: 232dda6cbc10860328a83517a6e3ea238ff4147f branch: master author: Victor Stinner committer: GitHub date: 2020-06-04T15:19:02+02:00 summary: bpo-40679: Fix _PyEval_EvalCode() crash if qualname is NULL (GH-20615) If name is NULL, name is now set to co->co_name. If qualname is NULL, qualname is now set to name. qualname must not be NULL: it is used to build error messages. Cleanup also the code: declare variables where they are initialized. Rename "name" local variables to "varname" to avoid overriding "name" parameter. files: A Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst M Python/ceval.c diff --git a/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst b/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst new file mode 100644 index 0000000000000..ccf908cef1914 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-03-17-48-13.bpo-40679.3sgWma.rst @@ -0,0 +1 @@ +Fix a ``_PyEval_EvalCode()`` crash if *qualname* argument is NULL. diff --git a/Python/ceval.c b/Python/ceval.c index 9ab8329d6d8e7..d1d0779318571 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4107,14 +4107,22 @@ _PyEval_EvalCode(PyThreadState *tstate, { assert(is_tstate_valid(tstate)); - PyCodeObject* co = (PyCodeObject*)_co; - PyFrameObject *f; + PyCodeObject *co = (PyCodeObject*)_co; + + if (!name) { + name = co->co_name; + } + assert(name != NULL); + assert(PyUnicode_Check(name)); + + if (!qualname) { + qualname = name; + } + assert(qualname != NULL); + assert(PyUnicode_Check(qualname)); + PyObject *retval = NULL; - PyObject **fastlocals, **freevars; - PyObject *x, *u; const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; - Py_ssize_t i, j, n; - PyObject *kwdict; if (globals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -4123,14 +4131,16 @@ _PyEval_EvalCode(PyThreadState *tstate, } /* Create the frame */ - f = _PyFrame_New_NoTrack(tstate, co, globals, locals); + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, co, globals, locals); if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; - freevars = f->f_localsplus + co->co_nlocals; + PyObject **fastlocals = f->f_localsplus; + PyObject **freevars = f->f_localsplus + co->co_nlocals; /* Create a dictionary for keyword parameters (**kwags) */ + PyObject *kwdict; + Py_ssize_t i; if (co->co_flags & CO_VARKEYWORDS) { kwdict = PyDict_New(); if (kwdict == NULL) @@ -4146,6 +4156,7 @@ _PyEval_EvalCode(PyThreadState *tstate, } /* Copy all positional arguments into local variables */ + Py_ssize_t j, n; if (argcount > co->co_argcount) { n = co->co_argcount; } @@ -4153,14 +4164,14 @@ _PyEval_EvalCode(PyThreadState *tstate, n = argcount; } for (j = 0; j < n; j++) { - x = args[j]; + PyObject *x = args[j]; Py_INCREF(x); SETLOCAL(j, x); } /* Pack other positional arguments into the *args argument */ if (co->co_flags & CO_VARARGS) { - u = _PyTuple_FromArray(args + n, argcount - n); + PyObject *u = _PyTuple_FromArray(args + n, argcount - n); if (u == NULL) { goto fail; } @@ -4186,16 +4197,16 @@ _PyEval_EvalCode(PyThreadState *tstate, normally interned this should almost always hit. */ co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *name = co_varnames[j]; - if (name == keyword) { + PyObject *varname = co_varnames[j]; + if (varname == keyword) { goto kw_found; } } /* Slow fallback, just in case */ for (j = co->co_posonlyargcount; j < total_args; j++) { - PyObject *name = co_varnames[j]; - int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ); + PyObject *varname = co_varnames[j]; + int cmp = PyObject_RichCompareBool( keyword, varname, Py_EQ); if (cmp > 0) { goto kw_found; } @@ -4209,7 +4220,8 @@ _PyEval_EvalCode(PyThreadState *tstate, if (co->co_posonlyargcount && positional_only_passed_as_keyword(tstate, co, - kwcount, kwnames, qualname)) + kwcount, kwnames, + qualname)) { goto fail; } @@ -4238,7 +4250,8 @@ _PyEval_EvalCode(PyThreadState *tstate, /* Check the number of positional arguments */ if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(tstate, co, argcount, defcount, fastlocals, qualname); + too_many_positional(tstate, co, argcount, defcount, fastlocals, + qualname); goto fail; } @@ -4252,7 +4265,8 @@ _PyEval_EvalCode(PyThreadState *tstate, } } if (missing) { - missing_arguments(tstate, co, missing, defcount, fastlocals, qualname); + missing_arguments(tstate, co, missing, defcount, fastlocals, + qualname); goto fail; } if (n > m) @@ -4272,12 +4286,11 @@ _PyEval_EvalCode(PyThreadState *tstate, if (co->co_kwonlyargcount > 0) { Py_ssize_t missing = 0; for (i = co->co_argcount; i < total_args; i++) { - PyObject *name; if (GETLOCAL(i) != NULL) continue; - name = PyTuple_GET_ITEM(co->co_varnames, i); + PyObject *varname = PyTuple_GET_ITEM(co->co_varnames, i); if (kwdefs != NULL) { - PyObject *def = PyDict_GetItemWithError(kwdefs, name); + PyObject *def = PyDict_GetItemWithError(kwdefs, varname); if (def) { Py_INCREF(def); SETLOCAL(i, def); @@ -4290,7 +4303,8 @@ _PyEval_EvalCode(PyThreadState *tstate, missing++; } if (missing) { - missing_arguments(tstate, co, missing, -1, fastlocals, qualname); + missing_arguments(tstate, co, missing, -1, fastlocals, + qualname); goto fail; } } From webhook-mailer at python.org Thu Jun 4 15:58:19 2020 From: webhook-mailer at python.org (Harsha Laxman) Date: Thu, 04 Jun 2020 19:58:19 -0000 Subject: [Python-checkins] Fix spacing in docs for tarfile (GH-20629) Message-ID: https://github.com/python/cpython/commit/7a280197f4162e5fcdde6f34701a9fa6e669190d commit: 7a280197f4162e5fcdde6f34701a9fa6e669190d branch: master author: Harsha Laxman committer: GitHub date: 2020-06-04T12:58:10-07:00 summary: Fix spacing in docs for tarfile (GH-20629) Before ``` content.txt is 42 bytes in size and isa regular file. folder is 420 bytes in size and isa directory. magic is 4200 bytes in size and issomething else. ``` After: ``` content.txt is 42 bytes in size and is a regular file. folder is 420 bytes in size and is a directory. magic is 4200 bytes in size and is something else. ``` Automerge-Triggered-By: @orsenthil files: M Doc/library/tarfile.rst diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 459e4ad991d9d..c204263d3a094 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -787,7 +787,7 @@ How to read a gzip compressed tar archive and display some member information:: import tarfile tar = tarfile.open("sample.tar.gz", "r:gz") for tarinfo in tar: - print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="") + print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="") if tarinfo.isreg(): print("a regular file.") elif tarinfo.isdir(): From webhook-mailer at python.org Thu Jun 4 16:08:48 2020 From: webhook-mailer at python.org (Erlend Egeberg Aasland) Date: Thu, 04 Jun 2020 20:08:48 -0000 Subject: [Python-checkins] bpo-40865: Remove unused insint() macro from hash modules (GH-20627) Message-ID: https://github.com/python/cpython/commit/6ed578f6dbffdec94f62cc2e36d626fc195678d7 commit: 6ed578f6dbffdec94f62cc2e36d626fc195678d7 branch: master author: Erlend Egeberg Aasland committer: GitHub date: 2020-06-04T13:08:42-07:00 summary: bpo-40865: Remove unused insint() macro from hash modules (GH-20627) Automerge-Triggered-By: @tiran files: M Modules/md5module.c M Modules/sha1module.c M Modules/sha256module.c M Modules/sha512module.c diff --git a/Modules/md5module.c b/Modules/md5module.c index ea2bafb9b65e8..e4d9db40f22df 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -552,9 +552,6 @@ static struct PyMethodDef MD5_functions[] = { /* Initialize this module. */ -#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } - - static struct PyModuleDef _md5module = { PyModuleDef_HEAD_INIT, "_md5", diff --git a/Modules/sha1module.c b/Modules/sha1module.c index e066b88022941..b0656d83b3ae8 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -529,9 +529,6 @@ static struct PyMethodDef SHA1_functions[] = { /* Initialize this module. */ -#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } - - static struct PyModuleDef _sha1module = { PyModuleDef_HEAD_INIT, "_sha1", diff --git a/Modules/sha256module.c b/Modules/sha256module.c index e0ff9b2b3a187..8edb1d5382883 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -684,9 +684,6 @@ static struct PyMethodDef SHA_functions[] = { /* Initialize this module. */ -#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } - - static struct PyModuleDef _sha256module = { PyModuleDef_HEAD_INIT, "_sha256", diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 780f8e7f06c9e..561ef8ef0e867 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -741,9 +741,6 @@ static struct PyMethodDef SHA_functions[] = { /* Initialize this module. */ -#define insint(n,v) { PyModule_AddIntConstant(m,n,v); } - - static struct PyModuleDef _sha512module = { PyModuleDef_HEAD_INIT, "_sha512", From webhook-mailer at python.org Thu Jun 4 16:10:47 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 20:10:47 -0000 Subject: [Python-checkins] bpo-39573: Porting to Python 3.10: Py_SET_SIZE() macro (GH-20610) Message-ID: https://github.com/python/cpython/commit/dc24b8a2ac32114313bae519db3ccc21fe45c982 commit: dc24b8a2ac32114313bae519db3ccc21fe45c982 branch: master author: Victor Stinner committer: GitHub date: 2020-06-04T22:10:43+02:00 summary: bpo-39573: Porting to Python 3.10: Py_SET_SIZE() macro (GH-20610) In What's New in Python 3.10, propose Py_SET_SIZE(), Py_SET_REFCNT() and Py_SET_TYPE() macros for backward compatibility with Python 3.9 and older. files: M Doc/whatsnew/3.10.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 0b656475b7167..1234b2e6bbf27 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -135,17 +135,35 @@ Porting to Python 3.10 * Since :c:func:`Py_TYPE()` is changed to the inline static function, ``Py_TYPE(obj) = new_type`` must be replaced with ``Py_SET_TYPE(obj, new_type)``: - see :c:func:`Py_SET_TYPE()` (available since Python 3.9). + see :c:func:`Py_SET_TYPE()` (available since Python 3.9). For backward + compatibility, this macro can be used:: + + #if PY_VERSION_HEX < 0x030900A4 + # define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0) + #endif + (Contributed by Dong-hee Na in :issue:`39573`.) * Since :c:func:`Py_REFCNT()` is changed to the inline static function, ``Py_REFCNT(obj) = new_refcnt`` must be replaced with ``Py_SET_REFCNT(obj, new_refcnt)``: - see :c:func:`Py_SET_REFCNT()` (available since Python 3.9). + see :c:func:`Py_SET_REFCNT()` (available since Python 3.9). For backward + compatibility, this macro can be used:: + + #if PY_VERSION_HEX < 0x030900A4 + # define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0) + #endif + (Contributed by Victor Stinner in :issue:`39573`.) * Since :c:func:`Py_SIZE()` is changed to the inline static function, ``Py_SIZE(obj) = new_size`` must be replaced with ``Py_SET_SIZE(obj, new_size)``: - see :c:func:`Py_SET_SIZE()` (available since Python 3.9). + see :c:func:`Py_SET_SIZE()` (available since Python 3.9). For backward + compatibility, this macro can be used:: + + #if PY_VERSION_HEX < 0x030900A4 + # define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0) + #endif + (Contributed by Victor Stinner in :issue:`39573`.) * Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed From webhook-mailer at python.org Thu Jun 4 16:19:51 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 04 Jun 2020 20:19:51 -0000 Subject: [Python-checkins] Fix spacing in docs for tarfile (GH-20629) Message-ID: https://github.com/python/cpython/commit/c935b33322843b3abfd930cd24b8806f3923f1cc commit: c935b33322843b3abfd930cd24b8806f3923f1cc branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-04T13:19:47-07:00 summary: Fix spacing in docs for tarfile (GH-20629) Before ``` content.txt is 42 bytes in size and isa regular file. folder is 420 bytes in size and isa directory. magic is 4200 bytes in size and issomething else. ``` After: ``` content.txt is 42 bytes in size and is a regular file. folder is 420 bytes in size and is a directory. magic is 4200 bytes in size and is something else. ``` Automerge-Triggered-By: @orsenthil (cherry picked from commit 7a280197f4162e5fcdde6f34701a9fa6e669190d) Co-authored-by: Harsha Laxman files: M Doc/library/tarfile.rst diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index c34f2c4a57024..d60f1c8a5f2d8 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -784,7 +784,7 @@ How to read a gzip compressed tar archive and display some member information:: import tarfile tar = tarfile.open("sample.tar.gz", "r:gz") for tarinfo in tar: - print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="") + print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="") if tarinfo.isreg(): print("a regular file.") elif tarinfo.isdir(): From webhook-mailer at python.org Thu Jun 4 16:19:56 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 04 Jun 2020 20:19:56 -0000 Subject: [Python-checkins] Fix spacing in docs for tarfile (GH-20629) Message-ID: https://github.com/python/cpython/commit/6bfbe773bd84323a0894428db48a4d190b2909b9 commit: 6bfbe773bd84323a0894428db48a4d190b2909b9 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-04T13:19:51-07:00 summary: Fix spacing in docs for tarfile (GH-20629) Before ``` content.txt is 42 bytes in size and isa regular file. folder is 420 bytes in size and isa directory. magic is 4200 bytes in size and issomething else. ``` After: ``` content.txt is 42 bytes in size and is a regular file. folder is 420 bytes in size and is a directory. magic is 4200 bytes in size and is something else. ``` Automerge-Triggered-By: @orsenthil (cherry picked from commit 7a280197f4162e5fcdde6f34701a9fa6e669190d) Co-authored-by: Harsha Laxman files: M Doc/library/tarfile.rst diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 9cd07158e7f62..aa28441658973 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -779,7 +779,7 @@ How to read a gzip compressed tar archive and display some member information:: import tarfile tar = tarfile.open("sample.tar.gz", "r:gz") for tarinfo in tar: - print(tarinfo.name, "is", tarinfo.size, "bytes in size and is", end="") + print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="") if tarinfo.isreg(): print("a regular file.") elif tarinfo.isdir(): From webhook-mailer at python.org Thu Jun 4 17:38:44 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 21:38:44 -0000 Subject: [Python-checkins] bpo-40521: Make tuple free list per-interpreter (GH-20247) Message-ID: https://github.com/python/cpython/commit/69ac6e58fd98de339c013fe64cd1cf763e4f9bca commit: 69ac6e58fd98de339c013fe64cd1cf763e4f9bca branch: master author: Victor Stinner committer: GitHub date: 2020-06-04T23:38:36+02:00 summary: bpo-40521: Make tuple free list per-interpreter (GH-20247) Each interpreter now has its own tuple free lists: * Move tuple numfree and free_list arrays into PyInterpreterState. * Define PyTuple_MAXSAVESIZE and PyTuple_MAXFREELIST macros in pycore_interp.h. * Add _Py_tuple_state structure. Pass it explicitly to tuple_alloc(). * Add tstate parameter to _PyTuple_ClearFreeList() * Each interpreter now has its own empty tuple singleton. files: A Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Modules/gcmodule.c M Objects/tupleobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 0511eea779a7e..e8e5d32977095 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -166,7 +166,7 @@ PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); // Functions to clear types free lists extern void _PyFrame_ClearFreeList(void); -extern void _PyTuple_ClearFreeList(void); +extern void _PyTuple_ClearFreeList(PyThreadState *tstate); extern void _PyFloat_ClearFreeList(void); extern void _PyList_ClearFreeList(void); extern void _PyDict_ClearFreeList(void); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index f04ea330d0457..b90bfbe797b58 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -64,6 +64,26 @@ struct _Py_unicode_state { struct _Py_unicode_fs_codec fs_codec; }; +/* Speed optimization to avoid frequent malloc/free of small tuples */ +#ifndef PyTuple_MAXSAVESIZE + // Largest tuple to save on free list +# define PyTuple_MAXSAVESIZE 20 +#endif +#ifndef PyTuple_MAXFREELIST + // Maximum number of tuples of each size to save +# define PyTuple_MAXFREELIST 2000 +#endif + +struct _Py_tuple_state { +#if PyTuple_MAXSAVESIZE > 0 + /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, + entry 0 is the empty tuple () of which at most one instance + will be allocated. */ + PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; + int numfree[PyTuple_MAXSAVESIZE]; +#endif +}; + /* interpreter state */ @@ -157,6 +177,7 @@ struct _is { */ PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; #endif + struct _Py_tuple_state tuple; }; /* Used by _PyImport_Cleanup() */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 77ea3f27454da..3f2ff5bfd2410 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -60,7 +60,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate); extern void _PyFrame_Fini(void); extern void _PyDict_Fini(void); -extern void _PyTuple_Fini(void); +extern void _PyTuple_Fini(PyThreadState *tstate); extern void _PyList_Fini(void); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst new file mode 100644 index 0000000000000..f364d36a135f2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -0,0 +1 @@ +Each interpreter now has its own tuple free lists and empty tuple singleton. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index a44752b1cc4da..1f5aa936e41c7 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1025,8 +1025,9 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, static void clear_freelists(void) { + PyThreadState *tstate = _PyThreadState_GET(); _PyFrame_ClearFreeList(); - _PyTuple_ClearFreeList(); + _PyTuple_ClearFreeList(tstate); _PyFloat_ClearFreeList(); _PyList_ClearFreeList(); _PyDict_ClearFreeList(); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 43706c22b9291..951cd1faf7e8f 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -14,28 +14,6 @@ class tuple "PyTupleObject *" "&PyTuple_Type" #include "clinic/tupleobject.c.h" -/* Speed optimization to avoid frequent malloc/free of small tuples */ -#ifndef PyTuple_MAXSAVESIZE -#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */ -#endif -#ifndef PyTuple_MAXFREELIST -#define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */ -#endif - -/* bpo-40521: tuple free lists are shared by all interpreters. */ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -# undef PyTuple_MAXSAVESIZE -# define PyTuple_MAXSAVESIZE 0 -#endif - -#if PyTuple_MAXSAVESIZE > 0 -/* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty - tuple () of which at most one instance will be allocated. -*/ -static PyTupleObject *free_list[PyTuple_MAXSAVESIZE]; -static int numfree[PyTuple_MAXSAVESIZE]; -#endif - static inline void tuple_gc_track(PyTupleObject *op) { @@ -47,14 +25,14 @@ void _PyTuple_DebugMallocStats(FILE *out) { #if PyTuple_MAXSAVESIZE > 0 - int i; - char buf[128]; - for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + for (int i = 1; i < PyTuple_MAXSAVESIZE; i++) { + char buf[128]; PyOS_snprintf(buf, sizeof(buf), "free %d-sized PyTupleObject", i); - _PyDebugAllocatorStats(out, - buf, - numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i)); + _PyDebugAllocatorStats(out, buf, state->numfree[i], + _PyObject_VAR_SIZE(&PyTuple_Type, i)); } #endif } @@ -68,7 +46,7 @@ _PyTuple_DebugMallocStats(FILE *out) which wraps this function). */ static PyTupleObject * -tuple_alloc(Py_ssize_t size) +tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size) { PyTupleObject *op; if (size < 0) { @@ -76,10 +54,10 @@ tuple_alloc(Py_ssize_t size) return NULL; } #if PyTuple_MAXSAVESIZE > 0 - if (size < PyTuple_MAXSAVESIZE && (op = free_list[size]) != NULL) { + if (size < PyTuple_MAXSAVESIZE && (op = state->free_list[size]) != NULL) { assert(size != 0); - free_list[size] = (PyTupleObject *) op->ob_item[0]; - numfree[size]--; + state->free_list[size] = (PyTupleObject *) op->ob_item[0]; + state->numfree[size]--; /* Inline PyObject_InitVar */ #ifdef Py_TRACE_REFS Py_SET_SIZE(op, size); @@ -107,13 +85,15 @@ PyTuple_New(Py_ssize_t size) { PyTupleObject *op; #if PyTuple_MAXSAVESIZE > 0 - if (size == 0 && free_list[0]) { - op = free_list[0]; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + if (size == 0 && state->free_list[0]) { + op = state->free_list[0]; Py_INCREF(op); return (PyObject *) op; } #endif - op = tuple_alloc(size); + op = tuple_alloc(state, size); if (op == NULL) { return NULL; } @@ -122,8 +102,8 @@ PyTuple_New(Py_ssize_t size) } #if PyTuple_MAXSAVESIZE > 0 if (size == 0) { - free_list[0] = op; - ++numfree[0]; + state->free_list[0] = op; + ++state->numfree[0]; Py_INCREF(op); /* extra INCREF so that this is never freed */ } #endif @@ -210,8 +190,11 @@ PyTuple_Pack(Py_ssize_t n, ...) return PyTuple_New(0); } + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + va_start(vargs, n); - PyTupleObject *result = tuple_alloc(n); + PyTupleObject *result = tuple_alloc(state, n); if (result == NULL) { va_end(vargs); return NULL; @@ -233,22 +216,24 @@ PyTuple_Pack(Py_ssize_t n, ...) static void tupledealloc(PyTupleObject *op) { - Py_ssize_t i; Py_ssize_t len = Py_SIZE(op); PyObject_GC_UnTrack(op); Py_TRASHCAN_BEGIN(op, tupledealloc) if (len > 0) { - i = len; - while (--i >= 0) + Py_ssize_t i = len; + while (--i >= 0) { Py_XDECREF(op->ob_item[i]); + } #if PyTuple_MAXSAVESIZE > 0 + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; if (len < PyTuple_MAXSAVESIZE && - numfree[len] < PyTuple_MAXFREELIST && + state->numfree[len] < PyTuple_MAXFREELIST && Py_IS_TYPE(op, &PyTuple_Type)) { - op->ob_item[0] = (PyObject *) free_list[len]; - numfree[len]++; - free_list[len] = op; + op->ob_item[0] = (PyObject *) state->free_list[len]; + state->numfree[len]++; + state->free_list[len] = op; goto done; /* return */ } #endif @@ -423,7 +408,9 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) return PyTuple_New(0); } - PyTupleObject *tuple = tuple_alloc(n); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + PyTupleObject *tuple = tuple_alloc(state, n); if (tuple == NULL) { return NULL; } @@ -481,7 +468,8 @@ tupleconcat(PyTupleObject *a, PyObject *bb) Py_TYPE(bb)->tp_name); return NULL; } -#define b ((PyTupleObject *)bb) + PyTupleObject *b = (PyTupleObject *)bb; + if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { Py_INCREF(a); return (PyObject *)a; @@ -492,7 +480,9 @@ tupleconcat(PyTupleObject *a, PyObject *bb) return PyTuple_New(0); } - np = tuple_alloc(size); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + np = tuple_alloc(state, size); if (np == NULL) { return NULL; } @@ -512,7 +502,6 @@ tupleconcat(PyTupleObject *a, PyObject *bb) } tuple_gc_track(np); return (PyObject *)np; -#undef b } static PyObject * @@ -536,7 +525,9 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n) if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) return PyErr_NoMemory(); size = Py_SIZE(a) * n; - np = tuple_alloc(size); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + np = tuple_alloc(state, size); if (np == NULL) return NULL; p = np->ob_item; @@ -801,7 +792,9 @@ tuplesubscript(PyTupleObject* self, PyObject* item) return (PyObject *)self; } else { - PyTupleObject* result = tuple_alloc(slicelength); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_tuple_state *state = &interp->tuple; + PyTupleObject* result = tuple_alloc(state, slicelength); if (!result) return NULL; src = self->ob_item; @@ -963,13 +956,14 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } void -_PyTuple_ClearFreeList(void) +_PyTuple_ClearFreeList(PyThreadState *tstate) { #if PyTuple_MAXSAVESIZE > 0 + struct _Py_tuple_state *state = &tstate->interp->tuple; for (Py_ssize_t i = 1; i < PyTuple_MAXSAVESIZE; i++) { - PyTupleObject *p = free_list[i]; - free_list[i] = NULL; - numfree[i] = 0; + PyTupleObject *p = state->free_list[i]; + state->free_list[i] = NULL; + state->numfree[i] = 0; while (p) { PyTupleObject *q = p; p = (PyTupleObject *)(p->ob_item[0]); @@ -981,14 +975,15 @@ _PyTuple_ClearFreeList(void) } void -_PyTuple_Fini(void) +_PyTuple_Fini(PyThreadState *tstate) { #if PyTuple_MAXSAVESIZE > 0 + struct _Py_tuple_state *state = &tstate->interp->tuple; /* empty tuples are used all over the place and applications may * rely on the fact that an empty tuple is a singleton. */ - Py_CLEAR(free_list[0]); + Py_CLEAR(state->free_list[0]); - _PyTuple_ClearFreeList(); + _PyTuple_ClearFreeList(tstate); #endif } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index da66a82ada70a..9da3fb09c38ba 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1252,7 +1252,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) if (is_main_interp) { /* Sundry finalizers */ _PyFrame_Fini(); - _PyTuple_Fini(); + } + _PyTuple_Fini(tstate); + if (is_main_interp) { _PyList_Fini(); _PySet_Fini(); _PyBytes_Fini(); From webhook-mailer at python.org Thu Jun 4 18:50:20 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 22:50:20 -0000 Subject: [Python-checkins] bpo-40521: Make float free list per-interpreter (GH-20636) Message-ID: https://github.com/python/cpython/commit/2ba59370c3dda2ac229c14510e53a05074b133d1 commit: 2ba59370c3dda2ac229c14510e53a05074b133d1 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T00:50:05+02:00 summary: bpo-40521: Make float free list per-interpreter (GH-20636) Each interpreter now has its own float free list: * Move tuple numfree and free_list into PyInterpreterState. * Add _Py_float_state structure. * Add tstate parameter to _PyFloat_ClearFreeList() and _PyFloat_Fini(). files: M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Modules/gcmodule.c M Objects/floatobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index e8e5d32977095..f90d80be16878 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -167,7 +167,7 @@ PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); // Functions to clear types free lists extern void _PyFrame_ClearFreeList(void); extern void _PyTuple_ClearFreeList(PyThreadState *tstate); -extern void _PyFloat_ClearFreeList(void); +extern void _PyFloat_ClearFreeList(PyThreadState *tstate); extern void _PyList_ClearFreeList(void); extern void _PyDict_ClearFreeList(void); extern void _PyAsyncGen_ClearFreeLists(void); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index b90bfbe797b58..c0eed00f36581 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -84,6 +84,14 @@ struct _Py_tuple_state { #endif }; +struct _Py_float_state { + /* Special free list + free_list is a singly-linked list of available PyFloatObjects, + linked via abuse of their ob_type members. */ + int numfree; + PyFloatObject *free_list; +}; + /* interpreter state */ @@ -178,6 +186,7 @@ struct _is { PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; #endif struct _Py_tuple_state tuple; + struct _Py_float_state float_state; }; /* Used by _PyImport_Cleanup() */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 3f2ff5bfd2410..2643abca0f553 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -64,7 +64,7 @@ extern void _PyTuple_Fini(PyThreadState *tstate); extern void _PyList_Fini(void); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); -extern void _PyFloat_Fini(void); +extern void _PyFloat_Fini(PyThreadState *tstate); extern void _PySlice_Fini(void); extern void _PyAsyncGen_Fini(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index f364d36a135f2..016f11668ee44 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1 +1,2 @@ -Each interpreter now has its own tuple free lists and empty tuple singleton. +Tuple free lists, empty tuple singleton, and float free list are no longer +shared by all interpreters: each interpreter now its own free lists. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 1f5aa936e41c7..0bad0f8917f37 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1028,7 +1028,7 @@ clear_freelists(void) PyThreadState *tstate = _PyThreadState_GET(); _PyFrame_ClearFreeList(); _PyTuple_ClearFreeList(tstate); - _PyFloat_ClearFreeList(); + _PyFloat_ClearFreeList(tstate); _PyList_ClearFreeList(); _PyDict_ClearFreeList(); _PyAsyncGen_ClearFreeLists(); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 868b7298a9e8d..d72fd21f95faf 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -5,6 +5,8 @@ #include "Python.h" #include "pycore_dtoa.h" +#include "pycore_interp.h" // _PyInterpreterState.float_state +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include #include @@ -16,16 +18,9 @@ class float "PyObject *" "&PyFloat_Type" #include "clinic/floatobject.c.h" -/* Special free list - free_list is a singly-linked list of available PyFloatObjects, linked - via abuse of their ob_type members. -*/ - #ifndef PyFloat_MAXFREELIST -#define PyFloat_MAXFREELIST 100 +# define PyFloat_MAXFREELIST 100 #endif -static int numfree = 0; -static PyFloatObject *free_list = NULL; double PyFloat_GetMax(void) @@ -117,16 +112,19 @@ PyFloat_GetInfo(void) PyObject * PyFloat_FromDouble(double fval) { - PyFloatObject *op = free_list; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_float_state *state = &interp->float_state; + PyFloatObject *op = state->free_list; if (op != NULL) { - free_list = (PyFloatObject *) Py_TYPE(op); - numfree--; - } else { - op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject)); - if (!op) + state->free_list = (PyFloatObject *) Py_TYPE(op); + state->numfree--; + } + else { + op = PyObject_Malloc(sizeof(PyFloatObject)); + if (!op) { return PyErr_NoMemory(); + } } - /* Inline PyObject_New */ (void)PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; @@ -219,13 +217,15 @@ static void float_dealloc(PyFloatObject *op) { if (PyFloat_CheckExact(op)) { - if (numfree >= PyFloat_MAXFREELIST) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_float_state *state = &interp->float_state; + if (state->numfree >= PyFloat_MAXFREELIST) { PyObject_FREE(op); return; } - numfree++; - Py_SET_TYPE(op, (PyTypeObject *)free_list); - free_list = op; + state->numfree++; + Py_SET_TYPE(op, (PyTypeObject *)state->free_list); + state->free_list = op; } else Py_TYPE(op)->tp_free((PyObject *)op); @@ -1981,30 +1981,33 @@ _PyFloat_Init(void) } void -_PyFloat_ClearFreeList(void) +_PyFloat_ClearFreeList(PyThreadState *tstate) { - PyFloatObject *f = free_list, *next; + struct _Py_float_state *state = &tstate->interp->float_state; + PyFloatObject *f = state->free_list, *next; for (; f; f = next) { next = (PyFloatObject*) Py_TYPE(f); PyObject_FREE(f); } - free_list = NULL; - numfree = 0; + state->free_list = NULL; + state->numfree = 0; } void -_PyFloat_Fini(void) +_PyFloat_Fini(PyThreadState *tstate) { - _PyFloat_ClearFreeList(); + _PyFloat_ClearFreeList(tstate); } /* Print summary info about the state of the optimized allocator */ void _PyFloat_DebugMallocStats(FILE *out) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_float_state *state = &interp->float_state; _PyDebugAllocatorStats(out, "free PyFloatObject", - numfree, sizeof(PyFloatObject)); + state->numfree, sizeof(PyFloatObject)); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 9da3fb09c38ba..716303cffc764 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1261,9 +1261,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) } _PyLong_Fini(tstate); + _PyFloat_Fini(tstate); if (is_main_interp) { - _PyFloat_Fini(); _PyDict_Fini(); _PySlice_Fini(); } From webhook-mailer at python.org Thu Jun 4 19:14:48 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 23:14:48 -0000 Subject: [Python-checkins] bpo-40521: Make slice cache per-interpreter (GH-20637) Message-ID: https://github.com/python/cpython/commit/7daba6f221e713f7f60c613b246459b07d179f91 commit: 7daba6f221e713f7f60c613b246459b07d179f91 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T01:14:40+02:00 summary: bpo-40521: Make slice cache per-interpreter (GH-20637) Each interpreter now has its own slice cache: * Move slice cache into PyInterpreterState. * Add tstate parameter to _PySlice_Fini(). files: M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Objects/sliceobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index c0eed00f36581..70054efe7ec71 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -187,6 +187,10 @@ struct _is { #endif struct _Py_tuple_state tuple; struct _Py_float_state float_state; + + /* Using a cache is very effective since typically only a single slice is + created and then deleted again. */ + PySliceObject *slice_cache; }; /* Used by _PyImport_Cleanup() */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 2643abca0f553..bba9bd9b2bdb2 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -65,7 +65,7 @@ extern void _PyList_Fini(void); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); -extern void _PySlice_Fini(void); +extern void _PySlice_Fini(PyThreadState *tstate); extern void _PyAsyncGen_Fini(void); extern void PyOS_FiniInterrupts(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 016f11668ee44..74c7a499bdef0 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,2 +1,3 @@ -Tuple free lists, empty tuple singleton, and float free list are no longer -shared by all interpreters: each interpreter now its own free lists. +The tuple free lists, the empty tuple singleton, the float free list, and the +slice cache are no longer shared by all interpreters: each interpreter now has +its own free lists and caches. diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 391711f711aae..f97a570a787f0 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -15,7 +15,7 @@ this type and there is exactly one in existence. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_object.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() #include "structmember.h" // PyMemberDef static PyObject * @@ -95,16 +95,13 @@ PyObject _Py_EllipsisObject = { /* Slice object implementation */ -/* Using a cache is very effective since typically only a single slice is - * created and then deleted again - */ -static PySliceObject *slice_cache = NULL; -void _PySlice_Fini(void) +void _PySlice_Fini(PyThreadState *tstate) { - PySliceObject *obj = slice_cache; + PyInterpreterState *interp = tstate->interp; + PySliceObject *obj = interp->slice_cache; if (obj != NULL) { - slice_cache = NULL; + interp->slice_cache = NULL; PyObject_GC_Del(obj); } } @@ -116,10 +113,11 @@ void _PySlice_Fini(void) PyObject * PySlice_New(PyObject *start, PyObject *stop, PyObject *step) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PySliceObject *obj; - if (slice_cache != NULL) { - obj = slice_cache; - slice_cache = NULL; + if (interp->slice_cache != NULL) { + obj = interp->slice_cache; + interp->slice_cache = NULL; _Py_NewReference((PyObject *)obj); } else { obj = PyObject_GC_New(PySliceObject, &PySlice_Type); @@ -324,14 +322,17 @@ Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); static void slice_dealloc(PySliceObject *r) { + PyInterpreterState *interp = _PyInterpreterState_GET(); _PyObject_GC_UNTRACK(r); Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); - if (slice_cache == NULL) - slice_cache = r; - else + if (interp->slice_cache == NULL) { + interp->slice_cache = r; + } + else { PyObject_GC_Del(r); + } } static PyObject * diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 716303cffc764..ee9d698d7d089 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1265,9 +1265,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) if (is_main_interp) { _PyDict_Fini(); - _PySlice_Fini(); } + _PySlice_Fini(tstate); _PyWarnings_Fini(tstate->interp); if (is_main_interp) { From webhook-mailer at python.org Thu Jun 4 19:39:29 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 04 Jun 2020 23:39:29 -0000 Subject: [Python-checkins] bpo-40521: Make frame free list per-interpreter (GH-20638) Message-ID: https://github.com/python/cpython/commit/3744ed2c9c0b3905947602fc375de49533790cb9 commit: 3744ed2c9c0b3905947602fc375de49533790cb9 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T01:39:24+02:00 summary: bpo-40521: Make frame free list per-interpreter (GH-20638) Each interpreter now has its own frame free list: * Move frame free list into PyInterpreterState. * Add _Py_frame_state structure. * Add tstate parameter to _PyFrame_ClearFreeList() and _PyFrame_Fini(). * Remove "#if PyFrame_MAXFREELIST > 0". * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS". files: M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Modules/gcmodule.c M Objects/frameobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index f90d80be16878..01265d3f985b9 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -165,7 +165,7 @@ PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); // Functions to clear types free lists -extern void _PyFrame_ClearFreeList(void); +extern void _PyFrame_ClearFreeList(PyThreadState *tstate); extern void _PyTuple_ClearFreeList(PyThreadState *tstate); extern void _PyFloat_ClearFreeList(PyThreadState *tstate); extern void _PyList_ClearFreeList(void); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 70054efe7ec71..9b805f004eaa6 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -92,6 +92,12 @@ struct _Py_float_state { PyFloatObject *free_list; }; +struct _Py_frame_state { + PyFrameObject *free_list; + /* number of frames currently in free_list */ + int numfree; +}; + /* interpreter state */ @@ -187,6 +193,7 @@ struct _is { #endif struct _Py_tuple_state tuple; struct _Py_float_state float_state; + struct _Py_frame_state frame; /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index bba9bd9b2bdb2..06d2ac167d619 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -58,7 +58,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate); /* Various internal finalizers */ -extern void _PyFrame_Fini(void); +extern void _PyFrame_Fini(PyThreadState *tstate); extern void _PyDict_Fini(void); extern void _PyTuple_Fini(PyThreadState *tstate); extern void _PyList_Fini(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 74c7a499bdef0..71a1064ba7d14 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,3 +1,3 @@ -The tuple free lists, the empty tuple singleton, the float free list, and the -slice cache are no longer shared by all interpreters: each interpreter now has -its own free lists and caches. +The tuple free lists, the empty tuple singleton, the float free list, the slice +cache, and the frame free list are no longer shared by all interpreters: each +interpreter now its has own free lists and caches. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 0bad0f8917f37..45dc89d08c1fb 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1026,7 +1026,7 @@ static void clear_freelists(void) { PyThreadState *tstate = _PyThreadState_GET(); - _PyFrame_ClearFreeList(); + _PyFrame_ClearFreeList(tstate); _PyTuple_ClearFreeList(tstate); _PyFloat_ClearFreeList(tstate); _PyList_ClearFreeList(); diff --git a/Objects/frameobject.c b/Objects/frameobject.c index b6d073bd456d0..0fe9f2a6666b2 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -561,36 +561,25 @@ static PyGetSetDef frame_getsetlist[] = { /* max value for numfree */ #define PyFrame_MAXFREELIST 200 -/* bpo-40521: frame free lists are shared by all interpreters. */ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -# undef PyFrame_MAXFREELIST -# define PyFrame_MAXFREELIST 0 -#endif - -#if PyFrame_MAXFREELIST > 0 -static PyFrameObject *free_list = NULL; -static int numfree = 0; /* number of frames currently in free_list */ -#endif - static void _Py_HOT_FUNCTION frame_dealloc(PyFrameObject *f) { - PyObject **p, **valuestack; - PyCodeObject *co; - - if (_PyObject_GC_IS_TRACKED(f)) + if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); + } Py_TRASHCAN_SAFE_BEGIN(f) /* Kill all local variables */ - valuestack = f->f_valuestack; - for (p = f->f_localsplus; p < valuestack; p++) + PyObject **valuestack = f->f_valuestack; + for (PyObject **p = f->f_localsplus; p < valuestack; p++) { Py_CLEAR(*p); + } /* Free stack */ if (f->f_stacktop != NULL) { - for (p = valuestack; p < f->f_stacktop; p++) + for (PyObject **p = valuestack; p < f->f_stacktop; p++) { Py_XDECREF(*p); + } } Py_XDECREF(f->f_back); @@ -599,19 +588,21 @@ frame_dealloc(PyFrameObject *f) Py_CLEAR(f->f_locals); Py_CLEAR(f->f_trace); - co = f->f_code; + PyCodeObject *co = f->f_code; if (co->co_zombieframe == NULL) { co->co_zombieframe = f; } -#if PyFrame_MAXFREELIST > 0 - else if (numfree < PyFrame_MAXFREELIST) { - ++numfree; - f->f_back = free_list; - free_list = f; - } -#endif else { - PyObject_GC_Del(f); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_frame_state *state = &interp->frame; + if (state->numfree < PyFrame_MAXFREELIST) { + ++state->numfree; + f->f_back = state->free_list; + state->free_list = f; + } + else { + PyObject_GC_Del(f); + } } Py_DECREF(co); @@ -789,21 +780,20 @@ frame_alloc(PyCodeObject *code) Py_ssize_t ncells = PyTuple_GET_SIZE(code->co_cellvars); Py_ssize_t nfrees = PyTuple_GET_SIZE(code->co_freevars); Py_ssize_t extras = code->co_stacksize + code->co_nlocals + ncells + nfrees; -#if PyFrame_MAXFREELIST > 0 - if (free_list == NULL) -#endif + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_frame_state *state = &interp->frame; + if (state->free_list == NULL) { f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras); if (f == NULL) { return NULL; } } -#if PyFrame_MAXFREELIST > 0 else { - assert(numfree > 0); - --numfree; - f = free_list; - free_list = free_list->f_back; + assert(state->numfree > 0); + --state->numfree; + f = state->free_list; + state->free_list = state->free_list->f_back; if (Py_SIZE(f) < extras) { PyFrameObject *new_f = PyObject_GC_Resize(PyFrameObject, f, extras); if (new_f == NULL) { @@ -814,7 +804,6 @@ frame_alloc(PyCodeObject *code) } _Py_NewReference((PyObject *)f); } -#endif f->f_code = code; extras = code->co_nlocals + ncells + nfrees; @@ -1183,34 +1172,33 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) /* Clear out the free list */ void -_PyFrame_ClearFreeList(void) +_PyFrame_ClearFreeList(PyThreadState *tstate) { -#if PyFrame_MAXFREELIST > 0 - while (free_list != NULL) { - PyFrameObject *f = free_list; - free_list = free_list->f_back; + struct _Py_frame_state *state = &tstate->interp->frame; + while (state->free_list != NULL) { + PyFrameObject *f = state->free_list; + state->free_list = state->free_list->f_back; PyObject_GC_Del(f); - --numfree; + --state->numfree; } - assert(numfree == 0); -#endif + assert(state->numfree == 0); } void -_PyFrame_Fini(void) +_PyFrame_Fini(PyThreadState *tstate) { - _PyFrame_ClearFreeList(); + _PyFrame_ClearFreeList(tstate); } /* Print summary info about the state of the optimized allocator */ void _PyFrame_DebugMallocStats(FILE *out) { -#if PyFrame_MAXFREELIST > 0 + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_frame_state *state = &interp->frame; _PyDebugAllocatorStats(out, "free PyFrameObject", - numfree, sizeof(PyFrameObject)); -#endif + state->numfree, sizeof(PyFrameObject)); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ee9d698d7d089..1dbdbfdf5a318 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1249,10 +1249,7 @@ flush_std_files(void) static void finalize_interp_types(PyThreadState *tstate, int is_main_interp) { - if (is_main_interp) { - /* Sundry finalizers */ - _PyFrame_Fini(); - } + _PyFrame_Fini(tstate); _PyTuple_Fini(tstate); if (is_main_interp) { _PyList_Fini(); From webhook-mailer at python.org Thu Jun 4 19:40:29 2020 From: webhook-mailer at python.org (Cheryl Sabella) Date: Thu, 04 Jun 2020 23:40:29 -0000 Subject: [Python-checkins] bpo-40807: Show warnings once from codeop._maybe_compile (#20486) Message-ID: https://github.com/python/cpython/commit/052d3fc0907be253cfd64b2c737a0b0aca586011 commit: 052d3fc0907be253cfd64b2c737a0b0aca586011 branch: master author: Cheryl Sabella committer: GitHub date: 2020-06-04T19:40:24-04:00 summary: bpo-40807: Show warnings once from codeop._maybe_compile (#20486) * bpo-40807: Show warnings once from codeop._maybe_compile * Move catch_warnings * news Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst M Lib/codeop.py M Lib/test/test_codeop.py diff --git a/Lib/codeop.py b/Lib/codeop.py index 835e68c09ba27..7e192ea6a10a0 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -57,6 +57,7 @@ """ import __future__ +import warnings _features = [getattr(__future__, fname) for fname in __future__.all_feature_names] @@ -83,15 +84,18 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError: pass - try: - code1 = compiler(source + "\n", filename, symbol) - except SyntaxError as e: - err1 = e - - try: - code2 = compiler(source + "\n\n", filename, symbol) - except SyntaxError as e: - err2 = e + # Suppress warnings after the first compile to avoid duplication. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + code1 = compiler(source + "\n", filename, symbol) + except SyntaxError as e: + err1 = e + + try: + code2 = compiler(source + "\n\n", filename, symbol) + except SyntaxError as e: + err2 = e try: if code: diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 0c5e362feea0c..45cb1a7b74e90 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -303,6 +303,11 @@ def test_filename(self): self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, compile("a = 1\n", "def", 'single').co_filename) + def test_warning(self): + # Test that the warning is only returned once. + with support.check_warnings((".*literal", SyntaxWarning)) as w: + compile_command("0 is 0") + self.assertEqual(len(w.warnings), 1) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst new file mode 100644 index 0000000000000..532b809b77eed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst @@ -0,0 +1,2 @@ +Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). +from from emitting each warning three times. From webhook-mailer at python.org Thu Jun 4 20:05:50 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 05 Jun 2020 00:05:50 -0000 Subject: [Python-checkins] bpo-40521: Make list free list per-interpreter (GH-20642) Message-ID: https://github.com/python/cpython/commit/88ec9190105c9b03f49aaef601ce02b242a75273 commit: 88ec9190105c9b03f49aaef601ce02b242a75273 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T02:05:41+02:00 summary: bpo-40521: Make list free list per-interpreter (GH-20642) Each interpreter now has its own list free list: * Move list numfree and free_list into PyInterpreterState. * Add _Py_list_state structure. * Add tstate parameter to _PyList_ClearFreeList() and _PyList_Fini(). * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS". * _PyGC_Fini() clears gcstate->garbage list which can be stored in the list free list. Call _PyGC_Fini() before _PyList_Fini() to prevent leaking this list. files: M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Modules/gcmodule.c M Objects/listobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 01265d3f985b9..3388b4d69e264 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -168,7 +168,7 @@ PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); extern void _PyFrame_ClearFreeList(PyThreadState *tstate); extern void _PyTuple_ClearFreeList(PyThreadState *tstate); extern void _PyFloat_ClearFreeList(PyThreadState *tstate); -extern void _PyList_ClearFreeList(void); +extern void _PyList_ClearFreeList(PyThreadState *tstate); extern void _PyDict_ClearFreeList(void); extern void _PyAsyncGen_ClearFreeLists(void); extern void _PyContext_ClearFreeList(void); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 9b805f004eaa6..0eab246562051 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -84,6 +84,16 @@ struct _Py_tuple_state { #endif }; +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +# define PyList_MAXFREELIST 80 +#endif + +struct _Py_list_state { + PyListObject *free_list[PyList_MAXFREELIST]; + int numfree; +}; + struct _Py_float_state { /* Special free list free_list is a singly-linked list of available PyFloatObjects, @@ -192,6 +202,7 @@ struct _is { PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; #endif struct _Py_tuple_state tuple; + struct _Py_list_state list; struct _Py_float_state float_state; struct _Py_frame_state frame; diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 06d2ac167d619..3c35ca23eab1a 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -61,7 +61,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate); extern void _PyFrame_Fini(PyThreadState *tstate); extern void _PyDict_Fini(void); extern void _PyTuple_Fini(PyThreadState *tstate); -extern void _PyList_Fini(void); +extern void _PyList_Fini(PyThreadState *tstate); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 71a1064ba7d14..54cc60036164e 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,3 +1,3 @@ -The tuple free lists, the empty tuple singleton, the float free list, the slice -cache, and the frame free list are no longer shared by all interpreters: each -interpreter now its has own free lists and caches. +The tuple free lists, the empty tuple singleton, the list free list, the float +free list, the slice cache, and the frame free list are no longer shared by all +interpreters: each interpreter now its has own free lists and caches. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 45dc89d08c1fb..2f062d0022589 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1029,7 +1029,7 @@ clear_freelists(void) _PyFrame_ClearFreeList(tstate); _PyTuple_ClearFreeList(tstate); _PyFloat_ClearFreeList(tstate); - _PyList_ClearFreeList(); + _PyList_ClearFreeList(tstate); _PyDict_ClearFreeList(); _PyAsyncGen_ClearFreeLists(); _PyContext_ClearFreeList(); diff --git a/Objects/listobject.c b/Objects/listobject.c index 30d2620753744..043256d8adbf5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -96,65 +96,59 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) return 0; } -/* Empty list reuse scheme to save calls to malloc and free */ -#ifndef PyList_MAXFREELIST -# define PyList_MAXFREELIST 80 -#endif - -/* bpo-40521: list free lists are shared by all interpreters. */ -#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS -# undef PyList_MAXFREELIST -# define PyList_MAXFREELIST 0 -#endif - -static PyListObject *free_list[PyList_MAXFREELIST]; -static int numfree = 0; - void -_PyList_ClearFreeList(void) +_PyList_ClearFreeList(PyThreadState *tstate) { - while (numfree) { - PyListObject *op = free_list[--numfree]; + struct _Py_list_state *state = &tstate->interp->list; + while (state->numfree) { + PyListObject *op = state->free_list[--state->numfree]; assert(PyList_CheckExact(op)); PyObject_GC_Del(op); } } void -_PyList_Fini(void) +_PyList_Fini(PyThreadState *tstate) { - _PyList_ClearFreeList(); + _PyList_ClearFreeList(tstate); } /* Print summary info about the state of the optimized allocator */ void _PyList_DebugMallocStats(FILE *out) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_list_state *state = &interp->list; _PyDebugAllocatorStats(out, "free PyListObject", - numfree, sizeof(PyListObject)); + state->numfree, sizeof(PyListObject)); } PyObject * PyList_New(Py_ssize_t size) { - PyListObject *op; - if (size < 0) { PyErr_BadInternalCall(); return NULL; } - if (numfree) { - numfree--; - op = free_list[numfree]; + + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_list_state *state = &interp->list; + PyListObject *op; + if (state->numfree) { + state->numfree--; + op = state->free_list[state->numfree]; _Py_NewReference((PyObject *)op); - } else { + } + else { op = PyObject_GC_New(PyListObject, &PyList_Type); - if (op == NULL) + if (op == NULL) { return NULL; + } } - if (size <= 0) + if (size <= 0) { op->ob_item = NULL; + } else { op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *)); if (op->ob_item == NULL) { @@ -334,10 +328,14 @@ list_dealloc(PyListObject *op) } PyMem_FREE(op->ob_item); } - if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) - free_list[numfree++] = op; - else + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_list_state *state = &interp->list; + if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) { + state->free_list[state->numfree++] = op; + } + else { Py_TYPE(op)->tp_free((PyObject *)op); + } Py_TRASHCAN_END } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1dbdbfdf5a318..09d4d88404144 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1251,8 +1251,8 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) { _PyFrame_Fini(tstate); _PyTuple_Fini(tstate); + _PyList_Fini(tstate); if (is_main_interp) { - _PyList_Fini(); _PySet_Fini(); _PyBytes_Fini(); } @@ -1296,6 +1296,8 @@ finalize_interp_clear(PyThreadState *tstate) _PyGC_CollectNoFail(); } + _PyGC_Fini(tstate); + finalize_interp_types(tstate, is_main_interp); if (is_main_interp) { @@ -1309,8 +1311,6 @@ finalize_interp_clear(PyThreadState *tstate) _PyExc_Fini(); } - - _PyGC_Fini(tstate); } From webhook-mailer at python.org Thu Jun 4 20:34:22 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 05 Jun 2020 00:34:22 -0000 Subject: [Python-checkins] bpo-40521: Make async gen free lists per-interpreter (GH-20643) Message-ID: https://github.com/python/cpython/commit/78a02c2568714562e23e885b6dc5730601f35226 commit: 78a02c2568714562e23e885b6dc5730601f35226 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T02:34:14+02:00 summary: bpo-40521: Make async gen free lists per-interpreter (GH-20643) Each interpreter now has its own asynchronous generator free lists: * Move async gen free lists into PyInterpreterState. * Move _PyAsyncGen_MAXFREELIST define to pycore_interp.h * Add _Py_async_gen_state structure. * Add tstate parameter to _PyAsyncGen_ClearFreeLists and _PyAsyncGen_Fini(). files: M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Include/internal/pycore_pylifecycle.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Modules/gcmodule.c M Objects/genobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 3388b4d69e264..ad2e552df55f9 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -170,7 +170,7 @@ extern void _PyTuple_ClearFreeList(PyThreadState *tstate); extern void _PyFloat_ClearFreeList(PyThreadState *tstate); extern void _PyList_ClearFreeList(PyThreadState *tstate); extern void _PyDict_ClearFreeList(void); -extern void _PyAsyncGen_ClearFreeLists(void); +extern void _PyAsyncGen_ClearFreeLists(PyThreadState *tstate); extern void _PyContext_ClearFreeList(void); #ifdef __cplusplus diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 0eab246562051..d624218201b91 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -108,6 +108,23 @@ struct _Py_frame_state { int numfree; }; +#ifndef _PyAsyncGen_MAXFREELIST +# define _PyAsyncGen_MAXFREELIST 80 +#endif + +struct _Py_async_gen_state { + /* Freelists boost performance 6-10%; they also reduce memory + fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend + are short-living objects that are instantiated for every + __anext__() call. */ + struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST]; + int value_numfree; + + struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST]; + int asend_numfree; +}; + + /* interpreter state */ @@ -205,6 +222,7 @@ struct _is { struct _Py_list_state list; struct _Py_float_state float_state; struct _Py_frame_state frame; + struct _Py_async_gen_state async_gen; /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 3c35ca23eab1a..3e3657339a4a4 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -66,7 +66,7 @@ extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); extern void _PySlice_Fini(PyThreadState *tstate); -extern void _PyAsyncGen_Fini(void); +extern void _PyAsyncGen_Fini(PyThreadState *tstate); extern void PyOS_FiniInterrupts(void); diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index 54cc60036164e..f0fd5a1e13b79 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,3 +1,4 @@ The tuple free lists, the empty tuple singleton, the list free list, the float -free list, the slice cache, and the frame free list are no longer shared by all -interpreters: each interpreter now its has own free lists and caches. +free list, the slice cache, the frame free list, the asynchronous generator +free lists are no longer shared by all interpreters: each interpreter now its +has own free lists and caches. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 2f062d0022589..89e2db7b19495 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1031,7 +1031,7 @@ clear_freelists(void) _PyFloat_ClearFreeList(tstate); _PyList_ClearFreeList(tstate); _PyDict_ClearFreeList(); - _PyAsyncGen_ClearFreeLists(); + _PyAsyncGen_ClearFreeLists(tstate); _PyContext_ClearFreeList(); } diff --git a/Objects/genobject.c b/Objects/genobject.c index 1393f42533a59..f7dbfd7486419 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1162,7 +1162,7 @@ typedef enum { } AwaitableState; -typedef struct { +typedef struct PyAsyncGenASend { PyObject_HEAD PyAsyncGenObject *ags_gen; @@ -1174,7 +1174,7 @@ typedef struct { } PyAsyncGenASend; -typedef struct { +typedef struct PyAsyncGenAThrow { PyObject_HEAD PyAsyncGenObject *agt_gen; @@ -1186,28 +1186,12 @@ typedef struct { } PyAsyncGenAThrow; -typedef struct { +typedef struct _PyAsyncGenWrappedValue { PyObject_HEAD PyObject *agw_val; } _PyAsyncGenWrappedValue; -#ifndef _PyAsyncGen_MAXFREELIST -#define _PyAsyncGen_MAXFREELIST 80 -#endif - -/* Freelists boost performance 6-10%; they also reduce memory - fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend - are short-living objects that are instantiated for every - __anext__ call. -*/ - -static _PyAsyncGenWrappedValue *ag_value_freelist[_PyAsyncGen_MAXFREELIST]; -static int ag_value_freelist_free = 0; - -static PyAsyncGenASend *ag_asend_freelist[_PyAsyncGen_MAXFREELIST]; -static int ag_asend_freelist_free = 0; - #define _PyAsyncGenWrappedValue_CheckExact(o) \ Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type) @@ -1423,27 +1407,29 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) void -_PyAsyncGen_ClearFreeLists(void) +_PyAsyncGen_ClearFreeLists(PyThreadState *tstate) { - while (ag_value_freelist_free) { + struct _Py_async_gen_state *state = &tstate->interp->async_gen; + + while (state->value_numfree) { _PyAsyncGenWrappedValue *o; - o = ag_value_freelist[--ag_value_freelist_free]; + o = state->value_freelist[--state->value_numfree]; assert(_PyAsyncGenWrappedValue_CheckExact(o)); PyObject_GC_Del(o); } - while (ag_asend_freelist_free) { + while (state->asend_numfree) { PyAsyncGenASend *o; - o = ag_asend_freelist[--ag_asend_freelist_free]; + o = state->asend_freelist[--state->asend_numfree]; assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type)); PyObject_GC_Del(o); } } void -_PyAsyncGen_Fini(void) +_PyAsyncGen_Fini(PyThreadState *tstate) { - _PyAsyncGen_ClearFreeLists(); + _PyAsyncGen_ClearFreeLists(tstate); } @@ -1486,10 +1472,13 @@ async_gen_asend_dealloc(PyAsyncGenASend *o) _PyObject_GC_UNTRACK((PyObject *)o); Py_CLEAR(o->ags_gen); Py_CLEAR(o->ags_sendval); - if (ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_async_gen_state *state = &interp->async_gen; + if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) { assert(PyAsyncGenASend_CheckExact(o)); - ag_asend_freelist[ag_asend_freelist_free++] = o; - } else { + state->asend_freelist[state->asend_numfree++] = o; + } + else { PyObject_GC_Del(o); } } @@ -1641,11 +1630,14 @@ static PyObject * async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) { PyAsyncGenASend *o; - if (ag_asend_freelist_free) { - ag_asend_freelist_free--; - o = ag_asend_freelist[ag_asend_freelist_free]; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_async_gen_state *state = &interp->async_gen; + if (state->asend_numfree) { + state->asend_numfree--; + o = state->asend_freelist[state->asend_numfree]; _Py_NewReference((PyObject *)o); - } else { + } + else { o = PyObject_GC_New(PyAsyncGenASend, &_PyAsyncGenASend_Type); if (o == NULL) { return NULL; @@ -1673,10 +1665,13 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) { _PyObject_GC_UNTRACK((PyObject *)o); Py_CLEAR(o->agw_val); - if (ag_value_freelist_free < _PyAsyncGen_MAXFREELIST) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_async_gen_state *state = &interp->async_gen; + if (state->value_numfree < _PyAsyncGen_MAXFREELIST) { assert(_PyAsyncGenWrappedValue_CheckExact(o)); - ag_value_freelist[ag_value_freelist_free++] = o; - } else { + state->value_freelist[state->value_numfree++] = o; + } + else { PyObject_GC_Del(o); } } @@ -1740,12 +1735,15 @@ _PyAsyncGenValueWrapperNew(PyObject *val) _PyAsyncGenWrappedValue *o; assert(val); - if (ag_value_freelist_free) { - ag_value_freelist_free--; - o = ag_value_freelist[ag_value_freelist_free]; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_async_gen_state *state = &interp->async_gen; + if (state->value_numfree) { + state->value_numfree--; + o = state->value_freelist[state->value_numfree]; assert(_PyAsyncGenWrappedValue_CheckExact(o)); _Py_NewReference((PyObject*)o); - } else { + } + else { o = PyObject_GC_New(_PyAsyncGenWrappedValue, &_PyAsyncGenWrappedValue_Type); if (o == NULL) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 09d4d88404144..073973e1328d4 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1270,7 +1270,11 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) if (is_main_interp) { _Py_HashRandomization_Fini(); _PyArg_Fini(); - _PyAsyncGen_Fini(); + } + + _PyAsyncGen_Fini(tstate); + + if (is_main_interp) { _PyContext_Fini(); } From webhook-mailer at python.org Thu Jun 4 20:56:44 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 05 Jun 2020 00:56:44 -0000 Subject: [Python-checkins] bpo-40521: Make context free list per-interpreter (GH-20644) Message-ID: https://github.com/python/cpython/commit/e005ead49b1ee2b1507ceea94e6f89c28ecf1f81 commit: e005ead49b1ee2b1507ceea94e6f89c28ecf1f81 branch: master author: Victor Stinner committer: GitHub date: 2020-06-05T02:56:37+02:00 summary: bpo-40521: Make context free list per-interpreter (GH-20644) Each interpreter now has its own context free list: * Move context free list into PyInterpreterState. * Add _Py_context_state structure. * Add tstate parameter to _PyContext_ClearFreeList() and _PyContext_Fini(). * Pass tstate to clear_freelists(). files: M Include/internal/pycore_context.h M Include/internal/pycore_gc.h M Include/internal/pycore_interp.h M Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst M Modules/gcmodule.c M Python/context.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h index f665ad5c115b0..ea4b3c8ea738f 100644 --- a/Include/internal/pycore_context.h +++ b/Include/internal/pycore_context.h @@ -37,6 +37,6 @@ struct _pycontexttokenobject { int _PyContext_Init(void); -void _PyContext_Fini(void); +void _PyContext_Fini(PyThreadState *tstate); #endif /* !Py_INTERNAL_CONTEXT_H */ diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index ad2e552df55f9..fd3fb7f94cab0 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -171,7 +171,7 @@ extern void _PyFloat_ClearFreeList(PyThreadState *tstate); extern void _PyList_ClearFreeList(PyThreadState *tstate); extern void _PyDict_ClearFreeList(void); extern void _PyAsyncGen_ClearFreeLists(PyThreadState *tstate); -extern void _PyContext_ClearFreeList(void); +extern void _PyContext_ClearFreeList(PyThreadState *tstate); #ifdef __cplusplus } diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index d624218201b91..4f811023f7a04 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -124,6 +124,12 @@ struct _Py_async_gen_state { int asend_numfree; }; +struct _Py_context_state { + // List of free PyContext objects + PyContext *freelist; + int numfree; +}; + /* interpreter state */ @@ -223,6 +229,7 @@ struct _is { struct _Py_float_state float_state; struct _Py_frame_state frame; struct _Py_async_gen_state async_gen; + struct _Py_context_state context; /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst index f0fd5a1e13b79..39cb80447f6a9 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst @@ -1,4 +1,4 @@ The tuple free lists, the empty tuple singleton, the list free list, the float free list, the slice cache, the frame free list, the asynchronous generator -free lists are no longer shared by all interpreters: each interpreter now its -has own free lists and caches. +free lists, and the context free list are no longer shared by all interpreters: +each interpreter now its has own free lists and caches. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 89e2db7b19495..f68258d7a327c 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1023,16 +1023,15 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, * Clearing the free lists may give back memory to the OS earlier. */ static void -clear_freelists(void) +clear_freelists(PyThreadState *tstate) { - PyThreadState *tstate = _PyThreadState_GET(); _PyFrame_ClearFreeList(tstate); _PyTuple_ClearFreeList(tstate); _PyFloat_ClearFreeList(tstate); _PyList_ClearFreeList(tstate); _PyDict_ClearFreeList(); _PyAsyncGen_ClearFreeLists(tstate); - _PyContext_ClearFreeList(); + _PyContext_ClearFreeList(tstate); } // Show stats for objects in each generations @@ -1306,7 +1305,7 @@ collect(PyThreadState *tstate, int generation, /* Clear free list only during the collection of the highest * generation */ if (generation == NUM_GENERATIONS-1) { - clear_freelists(); + clear_freelists(tstate); } if (_PyErr_Occurred(tstate)) { diff --git a/Python/context.c b/Python/context.c index bacc7010c458e..3cf8db4c90cdf 100644 --- a/Python/context.c +++ b/Python/context.c @@ -10,8 +10,6 @@ #define CONTEXT_FREELIST_MAXLEN 255 -static PyContext *ctx_freelist = NULL; -static int ctx_freelist_len = 0; #include "clinic/context.c.h" @@ -334,11 +332,13 @@ class _contextvars.Context "PyContext *" "&PyContext_Type" static inline PyContext * _context_alloc(void) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_context_state *state = &interp->context; PyContext *ctx; - if (ctx_freelist_len) { - ctx_freelist_len--; - ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + if (state->numfree) { + state->numfree--; + ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; _Py_NewReference((PyObject *)ctx); } @@ -458,10 +458,12 @@ context_tp_dealloc(PyContext *self) } (void)context_tp_clear(self); - if (ctx_freelist_len < CONTEXT_FREELIST_MAXLEN) { - ctx_freelist_len++; - self->ctx_weakreflist = (PyObject *)ctx_freelist; - ctx_freelist = self; + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_context_state *state = &interp->context; + if (state->numfree < CONTEXT_FREELIST_MAXLEN) { + state->numfree++; + self->ctx_weakreflist = (PyObject *)state->freelist; + state->freelist = self; } else { Py_TYPE(self)->tp_free(self); @@ -1271,11 +1273,12 @@ get_token_missing(void) void -_PyContext_ClearFreeList(void) +_PyContext_ClearFreeList(PyThreadState *tstate) { - for (; ctx_freelist_len; ctx_freelist_len--) { - PyContext *ctx = ctx_freelist; - ctx_freelist = (PyContext *)ctx->ctx_weakreflist; + struct _Py_context_state *state = &tstate->interp->context; + for (; state->numfree; state->numfree--) { + PyContext *ctx = state->freelist; + state->freelist = (PyContext *)ctx->ctx_weakreflist; ctx->ctx_weakreflist = NULL; PyObject_GC_Del(ctx); } @@ -1283,10 +1286,10 @@ _PyContext_ClearFreeList(void) void -_PyContext_Fini(void) +_PyContext_Fini(PyThreadState *tstate) { Py_CLEAR(_token_missing); - _PyContext_ClearFreeList(); + _PyContext_ClearFreeList(tstate); _PyHamt_Fini(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 073973e1328d4..6d2eb1defc884 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1273,10 +1273,7 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) } _PyAsyncGen_Fini(tstate); - - if (is_main_interp) { - _PyContext_Fini(); - } + _PyContext_Fini(tstate); /* Cleanup Unicode implementation */ _PyUnicode_Fini(tstate); From webhook-mailer at python.org Thu Jun 4 22:42:51 2020 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Fri, 05 Jun 2020 02:42:51 -0000 Subject: [Python-checkins] [3.8] bpo-40807: Backport test_codeop change [GH-19670] Message-ID: https://github.com/python/cpython/commit/a5d6aba318ead9cc756ba750a70da41f5def3f8f commit: a5d6aba318ead9cc756ba750a70da41f5def3f8f branch: 3.8 author: Terry Jan Reedy committer: GitHub date: 2020-06-04T22:42:44-04:00 summary: [3.8] bpo-40807: Backport test_codeop change [GH-19670] A tiny sliver of a 3.9 PEG parser patch needed to backport the test added by #20486. files: M Lib/test/test_codeop.py diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 98da26fa5dab1..4d52d15fa0fb3 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -3,12 +3,12 @@ Nick Mathewson """ import unittest -from test.support import is_jython +from test import support from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT import io -if is_jython: +if support.is_jython: import sys def unify_callables(d): @@ -21,7 +21,7 @@ class CodeopTests(unittest.TestCase): def assertValid(self, str, symbol='single'): '''succeed iff str is a valid piece of code''' - if is_jython: + if support.is_jython: code = compile_command(str, "", symbol) self.assertTrue(code) if symbol == "single": @@ -60,7 +60,7 @@ def test_valid(self): av = self.assertValid # special case - if not is_jython: + if not support.is_jython: self.assertEqual(compile_command(""), compile("pass", "", 'single', PyCF_DONT_IMPLY_DEDENT)) From webhook-mailer at python.org Thu Jun 4 23:00:59 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 05 Jun 2020 03:00:59 -0000 Subject: [Python-checkins] [3.8] bpo-40807: Backport test_codeop change [GH-19670] Message-ID: https://github.com/python/cpython/commit/12d3061c7819a73d891dcce44327410eaf0e1bc2 commit: 12d3061c7819a73d891dcce44327410eaf0e1bc2 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-04T23:00:47-04:00 summary: [3.8] bpo-40807: Backport test_codeop change [GH-19670] A tiny sliver of a 3.9 PEG parser patch needed to backport the test added by GH-20486. (cherry picked from commit a5d6aba318ead9cc756ba750a70da41f5def3f8f) Co-authored-by: Terry Jan Reedy files: M Lib/test/test_codeop.py diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 98da26fa5dab1..4d52d15fa0fb3 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -3,12 +3,12 @@ Nick Mathewson """ import unittest -from test.support import is_jython +from test import support from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT import io -if is_jython: +if support.is_jython: import sys def unify_callables(d): @@ -21,7 +21,7 @@ class CodeopTests(unittest.TestCase): def assertValid(self, str, symbol='single'): '''succeed iff str is a valid piece of code''' - if is_jython: + if support.is_jython: code = compile_command(str, "", symbol) self.assertTrue(code) if symbol == "single": @@ -60,7 +60,7 @@ def test_valid(self): av = self.assertValid # special case - if not is_jython: + if not support.is_jython: self.assertEqual(compile_command(""), compile("pass", "", 'single', PyCF_DONT_IMPLY_DEDENT)) From webhook-mailer at python.org Fri Jun 5 11:01:10 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Fri, 05 Jun 2020 15:01:10 -0000 Subject: [Python-checkins] bpo-1635741: Port mmap module to multiphase initialization (GH-19459) Message-ID: https://github.com/python/cpython/commit/3ad52e366fea37b02a3f619e6b7cffa7dfbdfa2e commit: 3ad52e366fea37b02a3f619e6b7cffa7dfbdfa2e branch: master author: Dong-hee Na committer: GitHub date: 2020-06-06T00:01:02+09:00 summary: bpo-1635741: Port mmap module to multiphase initialization (GH-19459) files: A Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst M Modules/mmapmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst b/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst new file mode 100644 index 0000000000000..cb849fb9b4430 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-04-10-23-54-57.bpo-1635741.ZURqoN.rst @@ -0,0 +1 @@ +Port :mod:`mmap` to multiphase initialization. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 8a60db1e1c469..463bd40e78f4f 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1509,157 +1509,163 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } #endif /* MS_WINDOWS */ -static void -setint(PyObject *d, const char *name, long value) +static int +mmap_exec(PyObject *module) { - PyObject *o = PyLong_FromLong(value); - if (o) { - PyDict_SetItemString(d, name, o); - Py_DECREF(o); + if (PyType_Ready(&mmap_object_type) < 0) { + return -1; } -} - -static struct PyModuleDef mmapmodule = { - PyModuleDef_HEAD_INIT, - "mmap", - NULL, - -1, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_mmap(void) -{ - PyObject *dict, *module; + Py_INCREF(PyExc_OSError); + if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { + Py_DECREF(PyExc_OSError); + return -1; + } + if (PyModule_AddType(module, &mmap_object_type) < 0) { + return -1; + } - if (PyType_Ready(&mmap_object_type) < 0) - return NULL; +#define ADD_INT_MACRO(module, constant) \ + do { \ + if (PyModule_AddIntConstant(module, #constant, constant) < 0) { \ + return -1; \ + } \ + } while (0) - module = PyModule_Create(&mmapmodule); - if (module == NULL) - return NULL; - dict = PyModule_GetDict(module); - if (!dict) - return NULL; - PyDict_SetItemString(dict, "error", PyExc_OSError); - PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type); #ifdef PROT_EXEC - setint(dict, "PROT_EXEC", PROT_EXEC); + ADD_INT_MACRO(module, PROT_EXEC); #endif #ifdef PROT_READ - setint(dict, "PROT_READ", PROT_READ); + ADD_INT_MACRO(module, PROT_READ); #endif #ifdef PROT_WRITE - setint(dict, "PROT_WRITE", PROT_WRITE); + ADD_INT_MACRO(module, PROT_WRITE); #endif #ifdef MAP_SHARED - setint(dict, "MAP_SHARED", MAP_SHARED); + ADD_INT_MACRO(module, MAP_SHARED); #endif #ifdef MAP_PRIVATE - setint(dict, "MAP_PRIVATE", MAP_PRIVATE); + ADD_INT_MACRO(module, MAP_PRIVATE); #endif #ifdef MAP_DENYWRITE - setint(dict, "MAP_DENYWRITE", MAP_DENYWRITE); + ADD_INT_MACRO(module, MAP_DENYWRITE); #endif #ifdef MAP_EXECUTABLE - setint(dict, "MAP_EXECUTABLE", MAP_EXECUTABLE); + ADD_INT_MACRO(module, MAP_EXECUTABLE); #endif #ifdef MAP_ANONYMOUS - setint(dict, "MAP_ANON", MAP_ANONYMOUS); - setint(dict, "MAP_ANONYMOUS", MAP_ANONYMOUS); + if (PyModule_AddIntConstant(module, "MAP_ANON", MAP_ANONYMOUS) < 0 ) { + return -1; + } + ADD_INT_MACRO(module, MAP_ANONYMOUS); #endif #ifdef MAP_POPULATE - setint(dict, "MAP_POPULATE", MAP_POPULATE); + ADD_INT_MACRO(module, MAP_POPULATE); #endif + if (PyModule_AddIntConstant(module, "PAGESIZE", (long)my_getpagesize()) < 0 ) { + return -1; + } - setint(dict, "PAGESIZE", (long)my_getpagesize()); - - setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); + if (PyModule_AddIntConstant(module, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()) < 0 ) { + return -1; + } - setint(dict, "ACCESS_DEFAULT", ACCESS_DEFAULT); - setint(dict, "ACCESS_READ", ACCESS_READ); - setint(dict, "ACCESS_WRITE", ACCESS_WRITE); - setint(dict, "ACCESS_COPY", ACCESS_COPY); + ADD_INT_MACRO(module, ACCESS_DEFAULT); + ADD_INT_MACRO(module, ACCESS_READ); + ADD_INT_MACRO(module, ACCESS_WRITE); + ADD_INT_MACRO(module, ACCESS_COPY); #ifdef HAVE_MADVISE // Conventional advice values #ifdef MADV_NORMAL - setint(dict, "MADV_NORMAL", MADV_NORMAL); + ADD_INT_MACRO(module, MADV_NORMAL); #endif #ifdef MADV_RANDOM - setint(dict, "MADV_RANDOM", MADV_RANDOM); + ADD_INT_MACRO(module, MADV_RANDOM); #endif #ifdef MADV_SEQUENTIAL - setint(dict, "MADV_SEQUENTIAL", MADV_SEQUENTIAL); + ADD_INT_MACRO(module, MADV_SEQUENTIAL); #endif #ifdef MADV_WILLNEED - setint(dict, "MADV_WILLNEED", MADV_WILLNEED); + ADD_INT_MACRO(module, MADV_WILLNEED); #endif #ifdef MADV_DONTNEED - setint(dict, "MADV_DONTNEED", MADV_DONTNEED); + ADD_INT_MACRO(module, MADV_DONTNEED); #endif // Linux-specific advice values #ifdef MADV_REMOVE - setint(dict, "MADV_REMOVE", MADV_REMOVE); + ADD_INT_MACRO(module, MADV_REMOVE); #endif #ifdef MADV_DONTFORK - setint(dict, "MADV_DONTFORK", MADV_DONTFORK); + ADD_INT_MACRO(module, MADV_DONTFORK); #endif #ifdef MADV_DOFORK - setint(dict, "MADV_DOFORK", MADV_DOFORK); + ADD_INT_MACRO(module, MADV_DOFORK); #endif #ifdef MADV_HWPOISON - setint(dict, "MADV_HWPOISON", MADV_HWPOISON); + ADD_INT_MACRO(module, MADV_HWPOISON); #endif #ifdef MADV_MERGEABLE - setint(dict, "MADV_MERGEABLE", MADV_MERGEABLE); + ADD_INT_MACRO(module, MADV_MERGEABLE); #endif #ifdef MADV_UNMERGEABLE - setint(dict, "MADV_UNMERGEABLE", MADV_UNMERGEABLE); + ADD_INT_MACRO(module, MADV_UNMERGEABLE); #endif #ifdef MADV_SOFT_OFFLINE - setint(dict, "MADV_SOFT_OFFLINE", MADV_SOFT_OFFLINE); + ADD_INT_MACRO(module, MADV_SOFT_OFFLINE); #endif #ifdef MADV_HUGEPAGE - setint(dict, "MADV_HUGEPAGE", MADV_HUGEPAGE); + ADD_INT_MACRO(module, MADV_HUGEPAGE); #endif #ifdef MADV_NOHUGEPAGE - setint(dict, "MADV_NOHUGEPAGE", MADV_NOHUGEPAGE); + ADD_INT_MACRO(module, MADV_NOHUGEPAGE); #endif #ifdef MADV_DONTDUMP - setint(dict, "MADV_DONTDUMP", MADV_DONTDUMP); + ADD_INT_MACRO(module, MADV_DONTDUMP); #endif #ifdef MADV_DODUMP - setint(dict, "MADV_DODUMP", MADV_DODUMP); + ADD_INT_MACRO(module, MADV_DODUMP); #endif #ifdef MADV_FREE // (Also present on FreeBSD and macOS.) - setint(dict, "MADV_FREE", MADV_FREE); + ADD_INT_MACRO(module, MADV_FREE); #endif // FreeBSD-specific #ifdef MADV_NOSYNC - setint(dict, "MADV_NOSYNC", MADV_NOSYNC); + ADD_INT_MACRO(module, MADV_NOSYNC); #endif #ifdef MADV_AUTOSYNC - setint(dict, "MADV_AUTOSYNC", MADV_AUTOSYNC); + ADD_INT_MACRO(module, MADV_AUTOSYNC); #endif #ifdef MADV_NOCORE - setint(dict, "MADV_NOCORE", MADV_NOCORE); + ADD_INT_MACRO(module, MADV_NOCORE); #endif #ifdef MADV_CORE - setint(dict, "MADV_CORE", MADV_CORE); + ADD_INT_MACRO(module, MADV_CORE); #endif #ifdef MADV_PROTECT - setint(dict, "MADV_PROTECT", MADV_PROTECT); + ADD_INT_MACRO(module, MADV_PROTECT); #endif #endif // HAVE_MADVISE + return 0; +} - return module; +static PyModuleDef_Slot mmap_slots[] = { + {Py_mod_exec, mmap_exec}, + {0, NULL} +}; + +static struct PyModuleDef mmapmodule = { + PyModuleDef_HEAD_INIT, + .m_name = "mmap", + .m_size = 0, + .m_slots = mmap_slots, +}; + +PyMODINIT_FUNC +PyInit_mmap(void) +{ + return PyModuleDef_Init(&mmapmodule); } From webhook-mailer at python.org Fri Jun 5 13:43:09 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Fri, 05 Jun 2020 17:43:09 -0000 Subject: [Python-checkins] bpo-40874: Update to libmpdec-2.5.0 (GH-20652) Message-ID: https://github.com/python/cpython/commit/087d612efebe7c64e5f079b07e0454111859830e commit: 087d612efebe7c64e5f079b07e0454111859830e branch: master author: Stefan Krah committer: GitHub date: 2020-06-05T19:43:01+02:00 summary: bpo-40874: Update to libmpdec-2.5.0 (GH-20652) files: M Modules/_decimal/libmpdec/basearith.c M Modules/_decimal/libmpdec/basearith.h M Modules/_decimal/libmpdec/bits.h M Modules/_decimal/libmpdec/constants.c M Modules/_decimal/libmpdec/constants.h M Modules/_decimal/libmpdec/context.c M Modules/_decimal/libmpdec/convolute.c M Modules/_decimal/libmpdec/convolute.h M Modules/_decimal/libmpdec/crt.c M Modules/_decimal/libmpdec/crt.h M Modules/_decimal/libmpdec/difradix2.c M Modules/_decimal/libmpdec/difradix2.h M Modules/_decimal/libmpdec/fnt.c M Modules/_decimal/libmpdec/fnt.h M Modules/_decimal/libmpdec/fourstep.c M Modules/_decimal/libmpdec/fourstep.h M Modules/_decimal/libmpdec/io.c M Modules/_decimal/libmpdec/io.h M Modules/_decimal/libmpdec/literature/fnt.py M Modules/_decimal/libmpdec/literature/matrix-transform.txt M Modules/_decimal/libmpdec/literature/mulmod-64.txt M Modules/_decimal/libmpdec/literature/mulmod-ppro.txt M Modules/_decimal/libmpdec/literature/six-step.txt M Modules/_decimal/libmpdec/literature/umodarith.lisp M Modules/_decimal/libmpdec/mpalloc.c M Modules/_decimal/libmpdec/mpalloc.h M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/libmpdec/mpdecimal.h M Modules/_decimal/libmpdec/numbertheory.c M Modules/_decimal/libmpdec/numbertheory.h M Modules/_decimal/libmpdec/sixstep.c M Modules/_decimal/libmpdec/sixstep.h M Modules/_decimal/libmpdec/transpose.c M Modules/_decimal/libmpdec/transpose.h M Modules/_decimal/libmpdec/typearith.h M Modules/_decimal/libmpdec/umodarith.h M Modules/_decimal/libmpdec/vccompat.h M Modules/_decimal/libmpdec/vcdiv64.asm diff --git a/Modules/_decimal/libmpdec/basearith.c b/Modules/_decimal/libmpdec/basearith.c index dfe1523927a40..85c608fadf515 100644 --- a/Modules/_decimal/libmpdec/basearith.c +++ b/Modules/_decimal/libmpdec/basearith.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,13 +27,13 @@ #include "mpdecimal.h" -#include -#include -#include + #include +#include + +#include "basearith.h" #include "constants.h" #include "typearith.h" -#include "basearith.h" /*********************************************************************/ @@ -337,6 +337,7 @@ _mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r, /* D2: loop */ for (j=m; j != MPD_SIZE_MAX; j--) { + assert(2 <= j+n && j+n <= nplusm); /* annotation for scan-build */ /* D3: calculate qhat and rhat */ rhat = _mpd_shortdiv(w2, u+j+n-1, 2, v[n-1]); @@ -652,6 +653,3 @@ _mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, return rem; } - - - diff --git a/Modules/_decimal/libmpdec/basearith.h b/Modules/_decimal/libmpdec/basearith.h index 976358a110ecf..d35925aaddb48 100644 --- a/Modules/_decimal/libmpdec/basearith.h +++ b/Modules/_decimal/libmpdec/basearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef BASEARITH_H -#define BASEARITH_H +#ifndef LIBMPDEC_BASEARITH_H_ +#define LIBMPDEC_BASEARITH_H_ #include "mpdecimal.h" -#include #include "typearith.h" @@ -216,7 +215,4 @@ _mpd_isallnine(const mpd_uint_t *data, mpd_ssize_t len) MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif /* BASEARITH_H */ - - - +#endif /* LIBMPDEC_BASEARITH_H_ */ diff --git a/Modules/_decimal/libmpdec/bits.h b/Modules/_decimal/libmpdec/bits.h index b5eaa24976ae5..aa9c3e77980c0 100644 --- a/Modules/_decimal/libmpdec/bits.h +++ b/Modules/_decimal/libmpdec/bits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef BITS_H -#define BITS_H +#ifndef LIBMPDEC_BITS_H_ +#define LIBMPDEC_BITS_H_ #include "mpdecimal.h" -#include /* Check if n is a power of 2. */ @@ -186,7 +185,4 @@ mpd_bsf(mpd_size_t a) #endif /* BSR/BSF */ -#endif /* BITS_H */ - - - +#endif /* LIBMPDEC_BITS_H_ */ diff --git a/Modules/_decimal/libmpdec/constants.c b/Modules/_decimal/libmpdec/constants.c index 2c2d5ea481035..4c4de622bc601 100644 --- a/Modules/_decimal/libmpdec/constants.c +++ b/Modules/_decimal/libmpdec/constants.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +27,6 @@ #include "mpdecimal.h" -#include #include "constants.h" @@ -128,5 +127,3 @@ const char *mpd_clamp_string[MPD_CLAMP_GUARD] = { "CLAMP_DEFAULT", "CLAMP_IEEE_754" }; - - diff --git a/Modules/_decimal/libmpdec/constants.h b/Modules/_decimal/libmpdec/constants.h index c0febfc8772d7..7c1db839c20ba 100644 --- a/Modules/_decimal/libmpdec/constants.h +++ b/Modules/_decimal/libmpdec/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,14 @@ */ -#ifndef CONSTANTS_H -#define CONSTANTS_H +#ifndef LIBMPDEC_CONSTANTS_H_ +#define LIBMPDEC_CONSTANTS_H_ #include "mpdecimal.h" +#include + /* Internal header file: all symbols have local scope in the DSO */ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) @@ -84,7 +86,4 @@ extern const mpd_uint_t UH_P1P2; MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif /* CONSTANTS_H */ - - - +#endif /* LIBMPDEC_CONSTANTS_H_ */ diff --git a/Modules/_decimal/libmpdec/context.c b/Modules/_decimal/libmpdec/context.c index 24c7b890c1d98..9cbc20509595d 100644 --- a/Modules/_decimal/libmpdec/context.c +++ b/Modules/_decimal/libmpdec/context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +27,16 @@ #include "mpdecimal.h" + +#include #include #include -#include void -mpd_dflt_traphandler(mpd_context_t *ctx UNUSED) +mpd_dflt_traphandler(mpd_context_t *ctx) { + (void)ctx; raise(SIGFPE); } @@ -282,5 +284,3 @@ mpd_addstatus_raise(mpd_context_t *ctx, uint32_t flags) mpd_traphandler(ctx); } } - - diff --git a/Modules/_decimal/libmpdec/convolute.c b/Modules/_decimal/libmpdec/convolute.c index 4c62e8bd3abd8..4bc8e8b5fd32f 100644 --- a/Modules/_decimal/libmpdec/convolute.c +++ b/Modules/_decimal/libmpdec/convolute.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,15 +27,14 @@ #include "mpdecimal.h" -#include #include "bits.h" #include "constants.h" +#include "convolute.h" #include "fnt.h" #include "fourstep.h" #include "numbertheory.h" #include "sixstep.h" #include "umodarith.h" -#include "convolute.h" /* Bignum: Fast convolution using the Number Theoretic Transform. Used for @@ -170,5 +169,3 @@ fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum) return 1; } - - diff --git a/Modules/_decimal/libmpdec/convolute.h b/Modules/_decimal/libmpdec/convolute.h index f30a177a68406..62edb3e45739c 100644 --- a/Modules/_decimal/libmpdec/convolute.h +++ b/Modules/_decimal/libmpdec/convolute.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef CONVOLUTE_H -#define CONVOLUTE_H +#ifndef LIBMPDEC_CONVOLUTE_H_ +#define LIBMPDEC_CONVOLUTE_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -47,4 +46,4 @@ int fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_CONVOLUTE_H_ */ diff --git a/Modules/_decimal/libmpdec/crt.c b/Modules/_decimal/libmpdec/crt.c index 4a1e80a232284..613274ee0c5b5 100644 --- a/Modules/_decimal/libmpdec/crt.c +++ b/Modules/_decimal/libmpdec/crt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,14 @@ #include "mpdecimal.h" -#include + #include + +#include "constants.h" +#include "crt.h" #include "numbertheory.h" #include "umodarith.h" -#include "crt.h" +#include "typearith.h" /* Bignum: Chinese Remainder Theorem, extends the maximum transform length. */ @@ -175,5 +178,3 @@ crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t rsize) assert(carry[0] == 0 && carry[1] == 0 && carry[2] == 0); } - - diff --git a/Modules/_decimal/libmpdec/crt.h b/Modules/_decimal/libmpdec/crt.h index f61e77293632e..15a347d4cb31e 100644 --- a/Modules/_decimal/libmpdec/crt.h +++ b/Modules/_decimal/libmpdec/crt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef CRT_H -#define CRT_H +#ifndef LIBMPDEC_CRT_H_ +#define LIBMPDEC_CRT_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -44,4 +43,4 @@ void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_CRT_H_ */ diff --git a/Modules/_decimal/libmpdec/difradix2.c b/Modules/_decimal/libmpdec/difradix2.c index 06e5ab5e222ee..049ecff65b6ee 100644 --- a/Modules/_decimal/libmpdec/difradix2.c +++ b/Modules/_decimal/libmpdec/difradix2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,12 +27,14 @@ #include "mpdecimal.h" -#include + #include + #include "bits.h" +#include "constants.h" +#include "difradix2.h" #include "numbertheory.h" #include "umodarith.h" -#include "difradix2.h" /* Bignum: The actual transform routine (decimation in frequency). */ @@ -169,5 +171,3 @@ fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams) bitreverse_permute(a, n); } - - diff --git a/Modules/_decimal/libmpdec/difradix2.h b/Modules/_decimal/libmpdec/difradix2.h index 5e22bcf324fac..cdcbcf9a71043 100644 --- a/Modules/_decimal/libmpdec/difradix2.h +++ b/Modules/_decimal/libmpdec/difradix2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef DIF_RADIX2_H -#define DIF_RADIX2_H +#ifndef LIBMPDEC_DIFRADIX2_H_ +#define LIBMPDEC_DIFRADIX2_H_ #include "mpdecimal.h" -#include #include "numbertheory.h" @@ -45,4 +44,4 @@ void fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_DIFRADIX2_H_ */ diff --git a/Modules/_decimal/libmpdec/fnt.c b/Modules/_decimal/libmpdec/fnt.c index 7e924c85242b0..0dbe98fc71c9e 100644 --- a/Modules/_decimal/libmpdec/fnt.c +++ b/Modules/_decimal/libmpdec/fnt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,13 +27,14 @@ #include "mpdecimal.h" -#include -#include + #include +#include + #include "bits.h" #include "difradix2.h" -#include "numbertheory.h" #include "fnt.h" +#include "numbertheory.h" /* Bignum: Fast transform for medium-sized coefficients. */ @@ -76,6 +77,3 @@ std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) mpd_free(tparams); return 1; } - - - diff --git a/Modules/_decimal/libmpdec/fnt.h b/Modules/_decimal/libmpdec/fnt.h index fa2154a798d45..5222c476a3a4f 100644 --- a/Modules/_decimal/libmpdec/fnt.h +++ b/Modules/_decimal/libmpdec/fnt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef FNT_H -#define FNT_H +#ifndef LIBMPDEC_FNT_H_ +#define LIBMPDEC_FNT_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -45,5 +44,4 @@ int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif - +#endif /* LIBMPDEC_FNT_H_ */ diff --git a/Modules/_decimal/libmpdec/fourstep.c b/Modules/_decimal/libmpdec/fourstep.c index 21d3e7485df4d..fb173ed5a52e4 100644 --- a/Modules/_decimal/libmpdec/fourstep.c +++ b/Modules/_decimal/libmpdec/fourstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,12 +27,14 @@ #include "mpdecimal.h" + #include + +#include "constants.h" +#include "fourstep.h" #include "numbertheory.h" #include "sixstep.h" -#include "transpose.h" #include "umodarith.h" -#include "fourstep.h" /* Bignum: Cache efficient Matrix Fourier Transform for arrays of the @@ -187,6 +189,7 @@ four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) #if 0 /* An unordered transform is sufficient for convolution. */ /* Transpose the matrix. */ + #include "transpose.h" transpose_3xpow2(a, R, C); #endif @@ -217,6 +220,7 @@ inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) #if 0 /* An unordered transform is sufficient for convolution. */ /* Transpose the matrix, producing an R*C matrix. */ + #include "transpose.h" transpose_3xpow2(a, C, R); #endif @@ -253,5 +257,3 @@ inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) return 1; } - - diff --git a/Modules/_decimal/libmpdec/fourstep.h b/Modules/_decimal/libmpdec/fourstep.h index 80dcd4be3d59b..5ffb6fcc8ecd0 100644 --- a/Modules/_decimal/libmpdec/fourstep.h +++ b/Modules/_decimal/libmpdec/fourstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef FOUR_STEP_H -#define FOUR_STEP_H +#ifndef LIBMPDEC_FOURSTEP_H_ +#define LIBMPDEC_FOURSTEP_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -45,4 +44,4 @@ int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_FOURSTEP_H_ */ diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c index f45e558f1a957..9513a68e3782d 100644 --- a/Modules/_decimal/libmpdec/io.c +++ b/Modules/_decimal/libmpdec/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,16 +27,16 @@ #include "mpdecimal.h" -#include -#include -#include -#include -#include + #include +#include #include +#include #include -#include "bits.h" -#include "constants.h" +#include +#include +#include + #include "typearith.h" #include "io.h" @@ -277,7 +277,7 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, } } - digits = end - coeff; + digits = end - coeff; if (dpoint) { size_t fracdigits = end-dpoint-1; if (dpoint > coeff) digits--; @@ -326,6 +326,22 @@ mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, mpd_seterror(dec, MPD_Conversion_syntax, status); } +/* convert a character string to a decimal, use a maxcontext for conversion */ +void +mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status) +{ + mpd_context_t maxcontext; + + mpd_maxcontext(&maxcontext); + mpd_qset_string(dec, s, &maxcontext, status); + + if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(dec, MPD_Invalid_operation, status); + } + *status &= MPD_Errors; +} + /* Print word x with n decimal digits to string s. dot is either NULL or the location of a decimal point. */ #define EXTRACT_DIGIT(s, x, d, dot) \ @@ -539,8 +555,8 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) dplace = -1 + mod_mpd_ssize_t(dec->exp+2, 3); } else { /* ldigits-1 is the adjusted exponent, which - * should be divisible by three. If not, move - * dplace one or two places to the right. */ + * should be divisible by three. If not, move + * dplace one or two places to the right. */ dplace += mod_mpd_ssize_t(ldigits-1, 3); } } @@ -1247,7 +1263,7 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, } if (isupper((uchar)type)) { - type = tolower((uchar)type); + type = (char)tolower((uchar)type); flags |= MPD_FMT_UPPER; } if (spec->sign == ' ') { @@ -1265,6 +1281,7 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, stackspec.align = '>'; spec = &stackspec; } + assert(strlen(spec->fill) == 1); /* annotation for scan-build */ if (type == '%') { flags |= MPD_FMT_PERCENT; } @@ -1579,5 +1596,3 @@ mpd_print(const mpd_t *dec) fputs("mpd_fprint: output error\n", stderr); /* GCOV_NOT_REACHED */ } } - - diff --git a/Modules/_decimal/libmpdec/io.h b/Modules/_decimal/libmpdec/io.h index de5486a00ca56..79d7c05ce369c 100644 --- a/Modules/_decimal/libmpdec/io.h +++ b/Modules/_decimal/libmpdec/io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,17 +26,20 @@ */ -#ifndef IO_H -#define IO_H +#ifndef LIBMPDEC_IO_H_ +#define LIBMPDEC_IO_H_ -#include #include "mpdecimal.h" +#include + #if SIZE_MAX == MPD_SIZE_MAX #define mpd_strtossize _mpd_strtossize #else +#include + static inline mpd_ssize_t mpd_strtossize(const char *s, char **end, int base) { @@ -56,4 +59,4 @@ mpd_strtossize(const char *s, char **end, int base) #endif -#endif +#endif /* LIBMPDEC_IO_H_ */ diff --git a/Modules/_decimal/libmpdec/literature/fnt.py b/Modules/_decimal/libmpdec/literature/fnt.py index 6363536da6487..c1285a565db96 100644 --- a/Modules/_decimal/libmpdec/literature/fnt.py +++ b/Modules/_decimal/libmpdec/literature/fnt.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008-2016 Stefan Krah. All rights reserved. +# Copyright (c) 2008-2020 Stefan Krah. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/literature/matrix-transform.txt b/Modules/_decimal/libmpdec/literature/matrix-transform.txt index 701d85d6b43c8..6e7ad7420909f 100644 --- a/Modules/_decimal/libmpdec/literature/matrix-transform.txt +++ b/Modules/_decimal/libmpdec/literature/matrix-transform.txt @@ -1,6 +1,6 @@ -(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) +(* Copyright (c) 2011-2020 Stefan Krah. All rights reserved. *) The Matrix Fourier Transform: diff --git a/Modules/_decimal/libmpdec/literature/mulmod-64.txt b/Modules/_decimal/libmpdec/literature/mulmod-64.txt index 029b8de3d7c92..fa967bf95e303 100644 --- a/Modules/_decimal/libmpdec/literature/mulmod-64.txt +++ b/Modules/_decimal/libmpdec/literature/mulmod-64.txt @@ -1,6 +1,6 @@ -(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) +(* Copyright (c) 2011-2020 Stefan Krah. All rights reserved. *) ========================================================================== diff --git a/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt b/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt index 4d17a928e6eae..ba804e4b4e786 100644 --- a/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt +++ b/Modules/_decimal/libmpdec/literature/mulmod-ppro.txt @@ -1,6 +1,6 @@ -(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) +(* Copyright (c) 2011-2020 Stefan Krah. All rights reserved. *) ======================================================================== diff --git a/Modules/_decimal/libmpdec/literature/six-step.txt b/Modules/_decimal/libmpdec/literature/six-step.txt index 8e45f48758478..852d5b0df8bf3 100644 --- a/Modules/_decimal/libmpdec/literature/six-step.txt +++ b/Modules/_decimal/libmpdec/literature/six-step.txt @@ -1,6 +1,6 @@ -(* Copyright (c) 2011 Stefan Krah. All rights reserved. *) +(* Copyright (c) 2011-2020 Stefan Krah. All rights reserved. *) The Six Step Transform: diff --git a/Modules/_decimal/libmpdec/literature/umodarith.lisp b/Modules/_decimal/libmpdec/literature/umodarith.lisp index 99d71c373d1ab..d71f074a26dcc 100644 --- a/Modules/_decimal/libmpdec/literature/umodarith.lisp +++ b/Modules/_decimal/libmpdec/literature/umodarith.lisp @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2016 Stefan Krah. All rights reserved. +; Copyright (c) 2008-2020 Stefan Krah. All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions @@ -149,7 +149,7 @@ (defthmd addmod-correct (implies (and (< 0 m) (< m base) - (< a m) (<= b m) + (< a m) (<= b m) (natp m) (natp base) (natp a) (natp b)) (equal (addmod a b m base) @@ -179,7 +179,7 @@ (defthmd submod-correct (implies (and (< 0 m) (< m base) - (< a m) (<= b m) + (< a m) (<= b m) (natp m) (natp base) (natp a) (natp b)) (equal (submod a b m base) @@ -200,7 +200,7 @@ (defthm submod-2-correct (implies (and (< 0 m) (< m base) - (< a m) (<= b m) + (< a m) (<= b m) (natp m) (natp base) (natp a) (natp b)) (equal (submod-2 a b m base) @@ -231,7 +231,7 @@ (defthmd ext-submod-ext-submod-2-equal (implies (and (< 0 m) (< m base) - (< a (* 2 m)) (< b (* 2 m)) + (< a (* 2 m)) (< b (* 2 m)) (natp m) (natp base) (natp a) (natp b)) (equal (ext-submod a b m base) @@ -239,7 +239,7 @@ (defthmd ext-submod-2-correct (implies (and (< 0 m) (< m base) - (< a (* 2 m)) (< b (* 2 m)) + (< a (* 2 m)) (< b (* 2 m)) (natp m) (natp base) (natp a) (natp b)) (equal (ext-submod-2 a b m base) @@ -257,7 +257,7 @@ (defthmd dw-reduce-correct (implies (and (< 0 m) (< m base) - (< hi base) (< lo base) + (< hi base) (< lo base) (natp m) (natp base) (natp hi) (natp lo)) (equal (dw-reduce hi lo m base) @@ -322,7 +322,7 @@ (defthmd dw-submod-correct (implies (and (< 0 m) (< m base) (natp a) (< a m) - (< hi base) (< lo base) + (< hi base) (< lo base) (natp m) (natp base) (natp hi) (natp lo)) (equal (dw-submod a hi lo m base) diff --git a/Modules/_decimal/libmpdec/mpalloc.c b/Modules/_decimal/libmpdec/mpalloc.c index a854e09911bd3..eb5ee7a807b33 100644 --- a/Modules/_decimal/libmpdec/mpalloc.c +++ b/Modules/_decimal/libmpdec/mpalloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,10 +27,14 @@ #include "mpdecimal.h" + +#include #include #include -#include "typearith.h" +#include + #include "mpalloc.h" +#include "typearith.h" #if defined(_MSC_VER) @@ -294,4 +298,59 @@ mpd_realloc_dyn(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) return 1; } +/* + * Input: 'result' is a static mpd_t with a static coefficient. + * Assumption: 'nwords' >= result->alloc. + * + * Resize the static coefficient to a larger dynamic one and copy the + * existing data. + * + * On failure the value of 'result' is unchanged. + */ +int +mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t nwords) +{ + assert(nwords >= result->alloc); + + mpd_uint_t *data = mpd_alloc(nwords, sizeof *result->data); + if (data == NULL) { + return 0; + } + + memcpy(data, result->data, result->alloc * (sizeof *result->data)); + result->data = data; + result->alloc = nwords; + mpd_set_dynamic_data(result); + return 1; +} +/* + * Input: 'result' is a static or a dynamic mpd_t with a dynamic coefficient. + * Resize the coefficient to length 'nwords': + * Case nwords > result->alloc: + * If realloc is successful: + * 'result' has a larger coefficient but the same value. Return 1. + * Otherwise: + * 'result' has a the same coefficient. Return 0. + * Case nwords < result->alloc: + * If realloc is successful: + * 'result' has a smaller coefficient. result->len is undefined. Return 1. + * Otherwise (unlikely): + * 'result' is unchanged. Reuse the now oversized coefficient. Return 1. + */ +int +mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t nwords) +{ + uint8_t err = 0; + + mpd_uint_t *p = mpd_realloc(result->data, nwords, sizeof *result->data, &err); + if (!err) { + result->data = p; + result->alloc = nwords; + } + else if (nwords > result->alloc) { + return 0; + } + + return 1; +} diff --git a/Modules/_decimal/libmpdec/mpalloc.h b/Modules/_decimal/libmpdec/mpalloc.h index efd711953a398..186808457b25c 100644 --- a/Modules/_decimal/libmpdec/mpalloc.h +++ b/Modules/_decimal/libmpdec/mpalloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,14 @@ */ -#ifndef MPALLOC_H -#define MPALLOC_H +#ifndef LIBMPDEC_MPALLOC_H_ +#define LIBMPDEC_MPALLOC_H_ #include "mpdecimal.h" +#include + /* Internal header file: all symbols have local scope in the DSO */ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) @@ -41,11 +43,11 @@ int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); - -MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ +int mpd_switch_to_dyn_cxx(mpd_t *result, mpd_ssize_t size); +int mpd_realloc_dyn_cxx(mpd_t *result, mpd_ssize_t size); -#endif - +MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ +#endif /* LIBMPDEC_MPALLOC_H_ */ diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 0986edb576a10..ad8db508b36f0 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,18 +27,21 @@ #include "mpdecimal.h" + +#include +#include +#include #include #include #include -#include -#include + #include "basearith.h" #include "bits.h" +#include "constants.h" #include "convolute.h" #include "crt.h" #include "mpalloc.h" #include "typearith.h" -#include "umodarith.h" #ifdef PPRO #if defined(_MSC_VER) @@ -241,7 +244,7 @@ mpd_lsd(mpd_uint_t word) } /* Coefficient size needed to store 'digits' */ -ALWAYS_INLINE mpd_ssize_t +mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits) { mpd_ssize_t q, r; @@ -260,8 +263,9 @@ mpd_exp_digits(mpd_ssize_t exp) /* Canonical */ ALWAYS_INLINE int -mpd_iscanonical(const mpd_t *dec UNUSED) +mpd_iscanonical(const mpd_t *dec) { + (void)dec; return 1; } @@ -512,6 +516,28 @@ mpd_qresize(mpd_t *result, mpd_ssize_t nwords, uint32_t *status) return mpd_realloc_dyn(result, nwords, status); } +/* Same as mpd_qresize, but do not set the result no NaN on failure. */ +static ALWAYS_INLINE int +mpd_qresize_cxx(mpd_t *result, mpd_ssize_t nwords) +{ + assert(!mpd_isconst_data(result)); /* illegal operation for a const */ + assert(!mpd_isshared_data(result)); /* illegal operation for a shared */ + assert(MPD_MINALLOC <= result->alloc); + + nwords = (nwords <= MPD_MINALLOC) ? MPD_MINALLOC : nwords; + if (nwords == result->alloc) { + return 1; + } + if (mpd_isstatic_data(result)) { + if (nwords > result->alloc) { + return mpd_switch_to_dyn_cxx(result, nwords); + } + return 1; + } + + return mpd_realloc_dyn_cxx(result, nwords); +} + /* Same as mpd_qresize, but the complete coefficient (including the old * memory area!) is initialized to zero. */ ALWAYS_INLINE int @@ -1192,7 +1218,7 @@ _c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status) result->data[i] = w[i]; } - mpd_set_sign(result, sign); + mpd_set_flags(result, sign); result->exp = 0; result->len = len; mpd_setdigits(result); @@ -1244,6 +1270,26 @@ mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, #endif } +/* quietly set a decimal from an int64_t, use a maxcontext for conversion */ +void +mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status) +{ + mpd_context_t maxcontext; + + mpd_maxcontext(&maxcontext); +#ifdef CONFIG_64 + mpd_qset_ssize(result, a, &maxcontext, status); +#else + _c32_qset_i64(result, a, &maxcontext, status); +#endif + + if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(result, MPD_Invalid_operation, status); + } + *status &= MPD_Errors; +} + /* quietly set a decimal from a uint64_t */ void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, @@ -1255,8 +1301,27 @@ mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, _c32_qset_u64(result, a, ctx, status); #endif } -#endif /* !LEGACY_COMPILER */ +/* quietly set a decimal from a uint64_t, use a maxcontext for conversion */ +void +mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status) +{ + mpd_context_t maxcontext; + + mpd_maxcontext(&maxcontext); +#ifdef CONFIG_64 + mpd_qset_uint(result, a, &maxcontext, status); +#else + _c32_qset_u64(result, a, &maxcontext, status); +#endif + + if (*status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) { + /* we want exact results */ + mpd_seterror(result, MPD_Invalid_operation, status); + } + *status &= MPD_Errors; +} +#endif /* !LEGACY_COMPILER */ /* * Quietly get an mpd_uint_t from a decimal. Assumes @@ -1345,11 +1410,13 @@ mpd_qabs_uint(const mpd_t *a, uint32_t *status) mpd_ssize_t mpd_qget_ssize(const mpd_t *a, uint32_t *status) { + uint32_t workstatus = 0; mpd_uint_t u; int isneg; - u = mpd_qabs_uint(a, status); - if (*status&MPD_Invalid_operation) { + u = mpd_qabs_uint(a, &workstatus); + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; return MPD_SSIZE_MAX; } @@ -1469,9 +1536,11 @@ mpd_qget_i64(const mpd_t *a, uint32_t *status) uint32_t mpd_qget_u32(const mpd_t *a, uint32_t *status) { - uint64_t x = mpd_qget_uint(a, status); + uint32_t workstatus = 0; + uint64_t x = mpd_qget_uint(a, &workstatus); - if (*status&MPD_Invalid_operation) { + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; return UINT32_MAX; } if (x > UINT32_MAX) { @@ -1486,9 +1555,11 @@ mpd_qget_u32(const mpd_t *a, uint32_t *status) int32_t mpd_qget_i32(const mpd_t *a, uint32_t *status) { - int64_t x = mpd_qget_ssize(a, status); + uint32_t workstatus = 0; + int64_t x = mpd_qget_ssize(a, &workstatus); - if (*status&MPD_Invalid_operation) { + if (workstatus&MPD_Invalid_operation) { + *status |= workstatus; return INT32_MAX; } if (x < INT32_MIN || x > INT32_MAX) { @@ -1504,14 +1575,20 @@ mpd_qget_i32(const mpd_t *a, uint32_t *status) uint64_t mpd_qget_u64(const mpd_t *a, uint32_t *status) { - return _c32_qget_u64(1, a, status); + uint32_t workstatus = 0; + uint64_t x = _c32_qget_u64(1, a, &workstatus); + *status |= workstatus; + return x; } /* quietly get an int64_t from a decimal */ int64_t mpd_qget_i64(const mpd_t *a, uint32_t *status) { - return _c32_qget_i64(a, status); + uint32_t workstatus = 0; + int64_t x = _c32_qget_i64(a, &workstatus); + *status |= workstatus; + return x; } #endif @@ -1937,6 +2014,25 @@ mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status) return 1; } +/* Same as mpd_qcopy, but do not set the result to NaN on failure. */ +int +mpd_qcopy_cxx(mpd_t *result, const mpd_t *a) +{ + if (result == a) return 1; + + if (!mpd_qresize_cxx(result, a->len)) { + return 0; + } + + mpd_copy_flags(result, a); + result->exp = a->exp; + result->digits = a->digits; + result->len = a->len; + memcpy(result->data, a->data, a->len * (sizeof *result->data)); + + return 1; +} + /* * Copy to a decimal with a static buffer. The caller has to make sure that * the buffer is big enough. Cannot fail. @@ -3780,11 +3876,31 @@ void mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); + MPD_NEW_STATIC(aa,0,0,0,0); + MPD_NEW_STATIC(bb,0,0,0,0); + uint32_t xstatus = 0; - if (*status & MPD_Malloc_error) { + if (q == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto out; + } + a = &aa; + } + + if (q == b) { + if (!mpd_qcopy(&bb, b, status)) { + mpd_seterror(q, MPD_Malloc_error, status); + goto out; + } + b = &bb; + } + + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, &xstatus); + + if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) { /* Inexact quotients (the usual case) fill the entire context precision, - * which can lead to malloc() failures for very high precisions. Retry + * which can lead to the above errors for very high precisions. Retry * the operation with a lower precision in case the result is exact. * * We need an upper bound for the number of digits of a_coeff / b_coeff @@ -3799,25 +3915,33 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, * We arrive at a total upper bound: * * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= - * a->digits + log2(b_coeff) = - * a->digits + log10(b_coeff) / log10(2) <= + * log10(a_coeff) + log2(b_coeff) = + * log10(a_coeff) + log10(b_coeff) / log10(2) <= * a->digits + b->digits * 4; */ - uint32_t workstatus = 0; mpd_context_t workctx = *ctx; + uint32_t ystatus = 0; + workctx.prec = a->digits + b->digits * 4; if (workctx.prec >= ctx->prec) { - return; /* No point in retrying, keep the original error. */ + *status |= (xstatus&MPD_Errors); + goto out; /* No point in retrying, keep the original error. */ } - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); - if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ - *status = 0; - return; + _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &ystatus); + if (ystatus != 0) { + ystatus = *status | ((ystatus|xstatus)&MPD_Errors); + mpd_seterror(q, ystatus, status); } - - mpd_seterror(q, *status, status); } + else { + *status |= xstatus; + } + + +out: + mpd_del(&aa); + mpd_del(&bb); } /* Internal function. */ @@ -3907,6 +4031,7 @@ _mpd_qdivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, } if (b->len == 1) { + assert(b->data[0] != 0); /* annotation for scan-build */ if (a->len == 1) { _mpd_div_word(&q->data[0], &r->data[0], a->data[0], b->data[0]); } @@ -6251,9 +6376,11 @@ _mpd_qpow_int(mpd_t *result, const mpd_t *base, const mpd_t *exp, workctx.round = MPD_ROUND_HALF_EVEN; workctx.clamp = 0; if (mpd_isnegative(exp)) { + uint32_t workstatus = 0; workctx.prec += 1; - mpd_qdiv(&tbase, &one, base, &workctx, status); - if (*status&MPD_Errors) { + mpd_qdiv(&tbase, &one, base, &workctx, &workstatus); + *status |= workstatus; + if (workstatus&MPD_Errors) { mpd_setspecial(result, MPD_POS, MPD_NAN); goto finish; } @@ -6988,6 +7115,8 @@ mpd_qrem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_ssize_t expdiff, qdigits; int cmp, isodd, allnine; + assert(r != NULL); /* annotation for scan-build */ + if (mpd_isspecial(a) || mpd_isspecial(b)) { if (mpd_qcheck_nans(r, a, b, ctx, status)) { return; @@ -7218,6 +7347,11 @@ void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status); } @@ -7226,6 +7360,12 @@ mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { mpd_context_t workctx = *ctx; + + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + workctx.round = MPD_ROUND_FLOOR; (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, &workctx, status); @@ -7236,6 +7376,12 @@ mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { mpd_context_t workctx = *ctx; + + if (mpd_isspecial(a)) { + mpd_seterror(result, MPD_Invalid_operation, status); + return; + } + workctx.round = MPD_ROUND_CEILING; (void)_mpd_qround_to_integral(TO_INT_SILENT, result, a, &workctx, status); @@ -7877,9 +8023,20 @@ void mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status) { - _mpd_qsqrt(result, a, ctx, status); + MPD_NEW_STATIC(aa,0,0,0,0); + uint32_t xstatus = 0; + + if (result == a) { + if (!mpd_qcopy(&aa, a, status)) { + mpd_seterror(result, MPD_Malloc_error, status); + goto out; + } + a = &aa; + } + + _mpd_qsqrt(result, a, ctx, &xstatus); - if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { + if (xstatus & (MPD_Malloc_error|MPD_Division_impossible)) { /* The above conditions can occur at very high context precisions * if intermediate values get too large. Retry the operation with * a lower context precision in case the result is exact. @@ -7889,22 +8046,27 @@ mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, * * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 */ - uint32_t workstatus = 0; + uint32_t ystatus = 0; mpd_context_t workctx = *ctx; - workctx.prec = a->digits; + workctx.prec = a->digits; if (workctx.prec >= ctx->prec) { - return; /* No point in repeating this, keep the original error. */ + *status |= (xstatus|MPD_Errors); + goto out; /* No point in repeating this, keep the original error. */ } - _mpd_qsqrt(result, a, &workctx, &workstatus); - if (workstatus == 0) { - *status = 0; - return; + _mpd_qsqrt(result, a, &workctx, &ystatus); + if (ystatus != 0) { + ystatus = *status | ((xstatus|ystatus)&MPD_Errors); + mpd_seterror(result, ystatus, status); } - - mpd_seterror(result, *status, status); } + else { + *status |= xstatus; + } + +out: + mpd_del(&aa); } @@ -7918,6 +8080,7 @@ mpd_sizeinbase(const mpd_t *a, uint32_t base) { double x; size_t digits; + double upper_bound; assert(mpd_isinteger(a)); assert(base >= 2); @@ -7934,10 +8097,14 @@ mpd_sizeinbase(const mpd_t *a, uint32_t base) if (digits > 2711437152599294ULL) { return SIZE_MAX; } + + upper_bound = (double)((1ULL<<53)-1); +#else + upper_bound = (double)(SIZE_MAX-1); #endif x = (double)digits / log10(base); - return (x > SIZE_MAX-1) ? SIZE_MAX : (size_t)x + 1; + return (x > upper_bound) ? SIZE_MAX : (size_t)x + 1; } /* Space needed to import a base 'base' integer of length 'srclen'. */ @@ -7945,6 +8112,7 @@ static mpd_ssize_t _mpd_importsize(size_t srclen, uint32_t base) { double x; + double upper_bound; assert(srclen > 0); assert(base >= 2); @@ -7953,10 +8121,15 @@ _mpd_importsize(size_t srclen, uint32_t base) if (srclen > (1ULL<<53)) { return MPD_SSIZE_MAX; } + + assert((1ULL<<53) <= MPD_MAXIMPORT); + upper_bound = (double)((1ULL<<53)-1); +#else + upper_bound = MPD_MAXIMPORT-1; #endif x = (double)srclen * (log10(base)/MPD_RDIGITS); - return (x >= MPD_MAXIMPORT) ? MPD_SSIZE_MAX : (mpd_ssize_t)x + 1; + return (x > upper_bound) ? MPD_SSIZE_MAX : (mpd_ssize_t)x + 1; } static uint8_t @@ -8483,6 +8656,3 @@ mpd_qimport_u32(mpd_t *result, mpd_qresize(result, result->len, status); mpd_qfinalize(result, ctx, status); } - - - diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h index a67dd9bc126c2..108b76efa8594 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.h +++ b/Modules/_decimal/libmpdec/mpdecimal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,59 +26,51 @@ */ -#ifndef MPDECIMAL_H -#define MPDECIMAL_H +#ifndef LIBMPDEC_MPDECIMAL_H_ +#define LIBMPDEC_MPDECIMAL_H_ +#ifndef _MSC_VER + #include "pyconfig.h" +#endif + #ifdef __cplusplus + #include + #include + #include + #include + #include extern "C" { - #ifndef __STDC_LIMIT_MACROS - #define __STDC_LIMIT_MACROS - #define MPD_CLEAR_STDC_LIMIT_MACROS - #endif +#else + #include + #include + #include + #include + #include #endif -#ifndef _MSC_VER - #include "pyconfig.h" +#if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \ + defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER) + #define MPD_PRAGMA(x) _Pragma(x) + #define MPD_HIDE_SYMBOLS_START "GCC visibility push(hidden)" + #define MPD_HIDE_SYMBOLS_END "GCC visibility pop" +#else + #define MPD_PRAGMA(x) + #define MPD_HIDE_SYMBOLS_START + #define MPD_HIDE_SYMBOLS_END #endif -#include -#include -#include -#include -#include -#include -#include +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) + #define UNUSED __attribute__((unused)) +#else + #define UNUSED +#endif -#ifdef _MSC_VER +#if defined(_MSC_VER) #include "vccompat.h" - #ifndef UNUSED - #define UNUSED - #endif - #define MPD_PRAGMA(x) - #define MPD_HIDE_SYMBOLS_START - #define MPD_HIDE_SYMBOLS_END #define EXTINLINE extern inline #else - #ifndef __GNUC_STDC_INLINE__ - #define __GNUC_STDC_INLINE__ 1 - #endif - #if defined(__GNUC__) && !defined(__INTEL_COMPILER) - #define UNUSED __attribute__((unused)) - #else - #define UNUSED - #endif - #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \ - defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER) - #define MPD_PRAGMA(x) _Pragma(x) - #define MPD_HIDE_SYMBOLS_START "GCC visibility push(hidden)" - #define MPD_HIDE_SYMBOLS_END "GCC visibility pop" - #else - #define MPD_PRAGMA(x) - #define MPD_HIDE_SYMBOLS_START - #define MPD_HIDE_SYMBOLS_END - #endif #define EXTINLINE #endif @@ -103,10 +95,10 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) /******************************************************************************/ #define MPD_MAJOR_VERSION 2 -#define MPD_MINOR_VERSION 4 -#define MPD_MICRO_VERSION 2 +#define MPD_MINOR_VERSION 5 +#define MPD_MICRO_VERSION 0 -#define MPD_VERSION "2.4.2" +#define MPD_VERSION "2.5.0" #define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ (MPD_MINOR_VERSION << 16) | \ @@ -423,6 +415,7 @@ void mpd_print(const mpd_t *dec); /* assignment from a string */ void mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_string_exact(mpd_t *dec, const char *s, uint32_t *status); /* set to NaN with error flags */ void mpd_seterror(mpd_t *result, uint32_t flags, uint32_t *status); @@ -440,6 +433,8 @@ void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t #ifndef LEGACY_COMPILER void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status); void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status); +void mpd_qset_i64_exact(mpd_t *result, int64_t a, uint32_t *status); +void mpd_qset_u64_exact(mpd_t *result, uint64_t a, uint32_t *status); #endif /* quietly assign a C integer type to an mpd_t with a static coefficient */ @@ -467,7 +462,8 @@ void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx); -int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status); +int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status); +int mpd_qcopy_cxx(mpd_t *result, const mpd_t *a); mpd_t *mpd_qncopy(const mpd_t *a); int mpd_qcopy_abs(mpd_t *result, const mpd_t *a, uint32_t *status); int mpd_qcopy_negate(mpd_t *result, const mpd_t *a, uint32_t *status); @@ -721,7 +717,7 @@ EXTINLINE mpd_uint_t mpd_lsd(mpd_uint_t word); EXTINLINE mpd_ssize_t mpd_digits_to_size(mpd_ssize_t digits); /* number of digits in the exponent, undefined for MPD_SSIZE_MIN */ EXTINLINE int mpd_exp_digits(mpd_ssize_t exp); -EXTINLINE int mpd_iscanonical(const mpd_t *dec UNUSED); +EXTINLINE int mpd_iscanonical(const mpd_t *dec); EXTINLINE int mpd_isfinite(const mpd_t *dec); EXTINLINE int mpd_isinfinite(const mpd_t *dec); EXTINLINE int mpd_isinteger(const mpd_t *dec); @@ -833,15 +829,8 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ #ifdef __cplusplus - #ifdef MPD_CLEAR_STDC_LIMIT_MACROS - #undef MPD_CLEAR_STDC_LIMIT_MACROS - #undef __STDC_LIMIT_MACROS - #endif } /* END extern "C" */ #endif -#endif /* MPDECIMAL_H */ - - - +#endif /* LIBMPDEC_MPDECIMAL_H_ */ diff --git a/Modules/_decimal/libmpdec/numbertheory.c b/Modules/_decimal/libmpdec/numbertheory.c index 4e035477e2800..210e0deb37120 100644 --- a/Modules/_decimal/libmpdec/numbertheory.c +++ b/Modules/_decimal/libmpdec/numbertheory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,11 +27,13 @@ #include "mpdecimal.h" -#include + #include +#include + #include "bits.h" -#include "umodarith.h" #include "numbertheory.h" +#include "umodarith.h" /* Bignum: Initialize the Number Theoretic Transform. */ @@ -128,5 +130,3 @@ _mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum) w3table[1] = kernel; w3table[2] = POWMOD(kernel, 2); } - - diff --git a/Modules/_decimal/libmpdec/numbertheory.h b/Modules/_decimal/libmpdec/numbertheory.h index e94c157910c83..47b7753b831b8 100644 --- a/Modules/_decimal/libmpdec/numbertheory.h +++ b/Modules/_decimal/libmpdec/numbertheory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,12 @@ */ -#ifndef NUMBER_THEORY_H -#define NUMBER_THEORY_H +#ifndef LIBMPDEC_NUMBERTHEORY_H_ +#define LIBMPDEC_NUMBERTHEORY_H_ -#include "constants.h" #include "mpdecimal.h" +#include "constants.h" /* Internal header file: all symbols have local scope in the DSO */ @@ -73,6 +73,4 @@ std_setmodulus(int modnum, mpd_uint_t *umod) MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif - - +#endif /* LIBMPDEC_NUMBERTHEORY_H_ */ diff --git a/Modules/_decimal/libmpdec/sixstep.c b/Modules/_decimal/libmpdec/sixstep.c index 92d513ebe1828..a4d1dbed7813c 100644 --- a/Modules/_decimal/libmpdec/sixstep.c +++ b/Modules/_decimal/libmpdec/sixstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,15 +27,17 @@ #include "mpdecimal.h" -#include -#include + #include +#include + #include "bits.h" +#include "constants.h" #include "difradix2.h" #include "numbertheory.h" +#include "sixstep.h" #include "transpose.h" #include "umodarith.h" -#include "sixstep.h" /* Bignum: Cache efficient Matrix Fourier Transform for arrays of the @@ -210,5 +212,3 @@ inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum) return 1; } - - diff --git a/Modules/_decimal/libmpdec/sixstep.h b/Modules/_decimal/libmpdec/sixstep.h index 4a8b015e3a9b9..89b4a33afc792 100644 --- a/Modules/_decimal/libmpdec/sixstep.h +++ b/Modules/_decimal/libmpdec/sixstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef SIX_STEP_H -#define SIX_STEP_H +#ifndef LIBMPDEC_SIXSTEP_H_ +#define LIBMPDEC_SIXSTEP_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -45,4 +44,4 @@ int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum); MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_SIXSTEP_H_ */ diff --git a/Modules/_decimal/libmpdec/transpose.c b/Modules/_decimal/libmpdec/transpose.c index 55d6d89922790..56321b5f39a73 100644 --- a/Modules/_decimal/libmpdec/transpose.c +++ b/Modules/_decimal/libmpdec/transpose.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,15 +27,17 @@ #include "mpdecimal.h" + +#include +#include #include #include #include -#include -#include + #include "bits.h" #include "constants.h" -#include "typearith.h" #include "transpose.h" +#include "typearith.h" #define BUFSIZE 4096 @@ -272,5 +274,3 @@ transpose_pow2(mpd_uint_t *matrix, mpd_size_t rows, mpd_size_t cols) return 1; } - - diff --git a/Modules/_decimal/libmpdec/transpose.h b/Modules/_decimal/libmpdec/transpose.h index e1cd1fa17dd77..e91c18d74356b 100644 --- a/Modules/_decimal/libmpdec/transpose.h +++ b/Modules/_decimal/libmpdec/transpose.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,11 @@ */ -#ifndef TRANSPOSE_H -#define TRANSPOSE_H +#ifndef LIBMPDEC_TRANSPOSE_H_ +#define LIBMPDEC_TRANSPOSE_H_ #include "mpdecimal.h" -#include /* Internal header file: all symbols have local scope in the DSO */ @@ -59,4 +58,4 @@ static inline void pointerswap(mpd_uint_t **a, mpd_uint_t **b) MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -#endif +#endif /* LIBMPDEC_TRANSPOSE_H_ */ diff --git a/Modules/_decimal/libmpdec/typearith.h b/Modules/_decimal/libmpdec/typearith.h index 405237dac516a..47961788d7641 100644 --- a/Modules/_decimal/libmpdec/typearith.h +++ b/Modules/_decimal/libmpdec/typearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,14 @@ */ -#ifndef TYPEARITH_H -#define TYPEARITH_H +#ifndef LIBMPDEC_TYPEARITH_H_ +#define LIBMPDEC_TYPEARITH_H_ #include "mpdecimal.h" +#include + /*****************************************************************************/ /* Low level native arithmetic on basic types */ @@ -663,7 +665,4 @@ mulmod_size_t(mpd_size_t a, mpd_size_t b, mpd_size_t m) } -#endif /* TYPEARITH_H */ - - - +#endif /* LIBMPDEC_TYPEARITH_H_ */ diff --git a/Modules/_decimal/libmpdec/umodarith.h b/Modules/_decimal/libmpdec/umodarith.h index 68d15188cb39e..d7dbbbe6a7331 100644 --- a/Modules/_decimal/libmpdec/umodarith.h +++ b/Modules/_decimal/libmpdec/umodarith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,12 +26,13 @@ */ -#ifndef UMODARITH_H -#define UMODARITH_H +#ifndef LIBMPDEC_UMODARITH_H_ +#define LIBMPDEC_UMODARITH_H_ -#include "constants.h" #include "mpdecimal.h" + +#include "constants.h" #include "typearith.h" @@ -644,7 +645,4 @@ ppro_powmod(mpd_uint_t base, mpd_uint_t exp, double *dmod, uint32_t *dinvmod) #endif /* CONFIG_32 */ -#endif /* UMODARITH_H */ - - - +#endif /* LIBMPDEC_UMODARITH_H_ */ diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/vccompat.h index 2ba805dcc5646..e2e1c42cc0250 100644 --- a/Modules/_decimal/libmpdec/vccompat.h +++ b/Modules/_decimal/libmpdec/vccompat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,14 +26,16 @@ */ -#ifndef VCCOMPAT_H -#define VCCOMPAT_H +#ifndef LIBMPDEC_VCCOMPAT_H_ +#define LIBMPDEC_VCCOMPAT_H_ /* Visual C fixes: no snprintf ... */ #ifdef _MSC_VER - #undef inline - #define inline __inline + #ifndef __cplusplus + #undef inline + #define inline __inline + #endif #undef random #define random rand #undef srandom @@ -51,7 +53,4 @@ #endif -#endif /* VCCOMPAT_H */ - - - +#endif /* LIBMPDEC_VCCOMPAT_H_ */ diff --git a/Modules/_decimal/libmpdec/vcdiv64.asm b/Modules/_decimal/libmpdec/vcdiv64.asm index 6b6645673ab5a..597e9ba9352c8 100644 --- a/Modules/_decimal/libmpdec/vcdiv64.asm +++ b/Modules/_decimal/libmpdec/vcdiv64.asm @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2016 Stefan Krah. All rights reserved. +; Copyright (c) 2008-2020 Stefan Krah. All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions @@ -44,5 +44,3 @@ _mpd_div_words PROC _mpd_div_words ENDP _TEXT ENDS END - - From webhook-mailer at python.org Fri Jun 5 16:01:27 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Fri, 05 Jun 2020 20:01:27 -0000 Subject: [Python-checkins] Fix missing FloatOperation in EXTRA_FUNCTIONALITY path. (#20655) Message-ID: https://github.com/python/cpython/commit/5fe1df1886e2e53b04bf76ef916857271d3c8f20 commit: 5fe1df1886e2e53b04bf76ef916857271d3c8f20 branch: master author: Stefan Krah committer: GitHub date: 2020-06-05T22:01:18+02:00 summary: Fix missing FloatOperation in EXTRA_FUNCTIONALITY path. (#20655) files: M Lib/test/test_decimal.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index f1abd2aecb122..ed483a4709527 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5201,6 +5201,7 @@ def test_c_signal_dict(self): DefaultContext = C.DefaultContext InvalidOperation = C.InvalidOperation + FloatOperation = C.FloatOperation DivisionByZero = C.DivisionByZero Overflow = C.Overflow Subnormal = C.Subnormal @@ -5274,6 +5275,7 @@ def assertIsExclusivelySet(signal, signal_dict): Underflow: C.DecUnderflow, Overflow: C.DecOverflow, DivisionByZero: C.DecDivisionByZero, + FloatOperation: C.DecFloatOperation, InvalidOperation: C.DecIEEEInvalidOperation } IntCond = [ From webhook-mailer at python.org Fri Jun 5 16:34:31 2020 From: webhook-mailer at python.org (Jason R. Coombs) Date: Fri, 05 Jun 2020 20:34:31 -0000 Subject: [Python-checkins] bpo-39791: Refresh importlib.metadata from importlib_metadata 1.6.1. (GH-20659) Message-ID: https://github.com/python/cpython/commit/161541ab45278df6603dd870113b10f13e4d9e16 commit: 161541ab45278df6603dd870113b10f13e4d9e16 branch: master author: Jason R. Coombs committer: GitHub date: 2020-06-05T16:34:16-04:00 summary: bpo-39791: Refresh importlib.metadata from importlib_metadata 1.6.1. (GH-20659) * Refresh importlib.metadata from importlib_metadata 1.6.1. * ?? Added by blurb_it. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst M Doc/library/importlib.metadata.rst M Lib/importlib/metadata.py M Lib/test/test_importlib/fixtures.py M Lib/test/test_importlib/test_main.py M Lib/test/test_importlib/test_zip.py diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 15e58b860d97d..21da143f3bebf 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -77,7 +77,9 @@ Entry points The ``entry_points()`` function returns a dictionary of all entry points, keyed by group. Entry points are represented by ``EntryPoint`` instances; each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and -a ``.load()`` method to resolve the value. +a ``.load()`` method to resolve the value. There are also ``.module``, +``.attr``, and ``.extras`` attributes for getting the components of the +``.value`` attribute:: >>> eps = entry_points() # doctest: +SKIP >>> list(eps) # doctest: +SKIP @@ -86,6 +88,12 @@ a ``.load()`` method to resolve the value. >>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0] # doctest: +SKIP >>> wheel # doctest: +SKIP EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts') + >>> wheel.module # doctest: +SKIP + 'wheel.cli' + >>> wheel.attr # doctest: +SKIP + 'main' + >>> wheel.extras # doctest: +SKIP + [] >>> main = wheel.load() # doctest: +SKIP >>> main # doctest: +SKIP @@ -94,7 +102,7 @@ The ``group`` and ``name`` are arbitrary values defined by the package author and usually a client will wish to resolve all entry points for a particular group. Read `the setuptools docs `_ -for more information on entrypoints, their definition, and usage. +for more information on entry points, their definition, and usage. .. _metadata: @@ -235,7 +243,7 @@ method:: """ The ``DistributionFinder.Context`` object provides ``.path`` and ``.name`` -properties indicating the path to search and names to match and may +properties indicating the path to search and name to match and may supply other relevant context. What this means in practice is that to support finding distribution package diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index 831f593277ccd..ffa0cba45706d 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -78,6 +78,16 @@ def load(self): attrs = filter(None, (match.group('attr') or '').split('.')) return functools.reduce(getattr, attrs, module) + @property + def module(self): + match = self.pattern.match(self.value) + return match.group('module') + + @property + def attr(self): + match = self.pattern.match(self.value) + return match.group('attr') + @property def extras(self): match = self.pattern.match(self.value) @@ -170,7 +180,7 @@ def from_name(cls, name): """ for resolver in cls._discover_resolvers(): dists = resolver(DistributionFinder.Context(name=name)) - dist = next(dists, None) + dist = next(iter(dists), None) if dist is not None: return dist else: @@ -213,6 +223,17 @@ def _discover_resolvers(): ) return filter(None, declared) + @classmethod + def _local(cls, root='.'): + from pep517 import build, meta + system = build.compat_system(root) + builder = functools.partial( + meta.build, + source_dir=root, + system=system, + ) + return PathDistribution(zipfile.Path(meta.build_as_zip(builder))) + @property def metadata(self): """Return the parsed metadata for this Distribution. @@ -391,7 +412,7 @@ class FastPath: def __init__(self, root): self.root = root - self.base = os.path.basename(root).lower() + self.base = os.path.basename(self.root).lower() def joinpath(self, child): return pathlib.Path(self.root, child) @@ -408,8 +429,8 @@ def zip_children(self): names = zip_path.root.namelist() self.joinpath = zip_path.joinpath - return ( - posixpath.split(child)[0] + return dict.fromkeys( + child.split(posixpath.sep, 1)[0] for child in names ) @@ -475,7 +496,6 @@ def _search_paths(cls, name, paths): ) - class PathDistribution(Distribution): def __init__(self, path): """Construct a distribution from a path to the metadata directory. diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index d923cec26ea8f..b25febb7fe756 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -161,6 +161,21 @@ def setUp(self): build_files(EggInfoFile.files, prefix=self.site_dir) +class LocalPackage: + files = { + "setup.py": """ + import setuptools + setuptools.setup(name="local-pkg", version="2.0.1") + """, + } + + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + self.fixtures.enter_context(tempdir_as_cwd()) + build_files(self.files) + + def build_files(file_defs, prefix=pathlib.Path()): """Build a set of files/directories, as described by the diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index 42a79992ecc8c..7b18c3de16eea 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -246,3 +246,19 @@ def test_json_dump(self): """ with self.assertRaises(Exception): json.dumps(self.ep) + + def test_module(self): + assert self.ep.module == 'value' + + def test_attr(self): + assert self.ep.attr is None + + +class FileSystem(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): + def test_unicode_dir_on_sys_path(self): + """ + Ensure a Unicode subdirectory of a directory on sys.path + does not crash. + """ + fixtures.build_files({'?': {}}, prefix=self.site_dir) + list(distributions()) diff --git a/Lib/test/test_importlib/test_zip.py b/Lib/test/test_importlib/test_zip.py index fa87cd7cb1096..a5399c16682fb 100644 --- a/Lib/test/test_importlib/test_zip.py +++ b/Lib/test/test_importlib/test_zip.py @@ -3,9 +3,10 @@ from contextlib import ExitStack from importlib.metadata import ( - distribution, entry_points, files, PackageNotFoundError, version, + distribution, entry_points, files, PackageNotFoundError, + version, distributions, ) -from importlib.resources import path +from importlib import resources from test.support import requires_zlib @@ -14,15 +15,19 @@ class TestZip(unittest.TestCase): root = 'test.test_importlib.data' + def _fixture_on_path(self, filename): + pkg_file = resources.files(self.root).joinpath(filename) + file = self.resources.enter_context(resources.as_file(pkg_file)) + assert file.name.startswith('example-'), file.name + sys.path.insert(0, str(file)) + self.resources.callback(sys.path.pop, 0) + def setUp(self): # Find the path to the example-*.whl so we can add it to the front of # sys.path, where we'll then try to find the metadata thereof. self.resources = ExitStack() self.addCleanup(self.resources.close) - wheel = self.resources.enter_context( - path(self.root, 'example-21.12-py3-none-any.whl')) - sys.path.insert(0, str(wheel)) - self.resources.callback(sys.path.pop, 0) + self._fixture_on_path('example-21.12-py3-none-any.whl') def test_zip_version(self): self.assertEqual(version('example'), '21.12') @@ -49,6 +54,10 @@ def test_files(self): path = str(file.dist.locate_file(file)) assert '.whl/' in path, path + def test_one_distribution(self): + dists = list(distributions(path=sys.path[:1])) + assert len(dists) == 1 + @requires_zlib() class TestEgg(TestZip): @@ -57,10 +66,7 @@ def setUp(self): # sys.path, where we'll then try to find the metadata thereof. self.resources = ExitStack() self.addCleanup(self.resources.close) - egg = self.resources.enter_context( - path(self.root, 'example-21.12-py3.6.egg')) - sys.path.insert(0, str(egg)) - self.resources.callback(sys.path.pop, 0) + self._fixture_on_path('example-21.12-py3.6.egg') def test_files(self): for file in files('example'): diff --git a/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst b/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst new file mode 100644 index 0000000000000..73e0cbb013f84 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-05-19-29-10.bpo-39791._CcO3d.rst @@ -0,0 +1 @@ +Refresh importlib.metadata from importlib_metadata 1.6.1. \ No newline at end of file From webhook-mailer at python.org Fri Jun 5 16:56:14 2020 From: webhook-mailer at python.org (Ram Rachum) Date: Fri, 05 Jun 2020 20:56:14 -0000 Subject: [Python-checkins] bpo-40876: Clarify error message in the csv module (GH-20653) Message-ID: https://github.com/python/cpython/commit/235f918f44bb89e27190db2f1823d191dbd4ad28 commit: 235f918f44bb89e27190db2f1823d191dbd4ad28 branch: master author: Ram Rachum committer: GitHub date: 2020-06-05T17:56:06-03:00 summary: bpo-40876: Clarify error message in the csv module (GH-20653) files: A Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst M Modules/_csv.c diff --git a/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst b/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst new file mode 100644 index 0000000000000..75f62addbabbc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-05-20-00-18.bpo-40876.zDhiZj.rst @@ -0,0 +1 @@ +Clarify error message in the :mod:`csv` module. diff --git a/Modules/_csv.c b/Modules/_csv.c index f33733aaf850d..7e44419c0876b 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -810,7 +810,7 @@ Reader_iternext(ReaderObj *self) PyErr_Format(_csvstate_global->error_obj, "iterator should return strings, " "not %.200s " - "(did you open the file in text mode?)", + "(the file should be opened in text mode)", Py_TYPE(lineobj)->tp_name ); Py_DECREF(lineobj); From webhook-mailer at python.org Fri Jun 5 17:32:18 2020 From: webhook-mailer at python.org (Erlend Egeberg Aasland) Date: Fri, 05 Jun 2020 21:32:18 -0000 Subject: [Python-checkins] bpo-40867: Remove unused include from Module/_randommodule.c (GH-20635) Message-ID: https://github.com/python/cpython/commit/45af786e111aed5f687e1f0d8b45b6a5e678a6bc commit: 45af786e111aed5f687e1f0d8b45b6a5e678a6bc branch: master author: Erlend Egeberg Aasland committer: GitHub date: 2020-06-05T14:32:09-07:00 summary: bpo-40867: Remove unused include from Module/_randommodule.c (GH-20635) files: M Modules/_randommodule.c diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 3589173edcb62..3e3139e4990cc 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -67,7 +67,6 @@ /* ---------------------------------------------------------------*/ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() #ifdef HAVE_PROCESS_H # include // getpid() #endif From webhook-mailer at python.org Fri Jun 5 19:52:20 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Fri, 05 Jun 2020 23:52:20 -0000 Subject: [Python-checkins] bpo-40883: Fix memory leak in fstring_compile_expr in parse_string.c (GH-20667) Message-ID: https://github.com/python/cpython/commit/a54096e30523534e8eebb8dc1011b4536ed237a8 commit: a54096e30523534e8eebb8dc1011b4536ed237a8 branch: master author: Pablo Galindo committer: GitHub date: 2020-06-06T00:52:15+01:00 summary: bpo-40883: Fix memory leak in fstring_compile_expr in parse_string.c (GH-20667) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst M Parser/pegen/parse_string.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst new file mode 100644 index 0000000000000..ebeb0cc60d16b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-23-25-00.bpo-40883.M6sQ-Q.rst @@ -0,0 +1 @@ +Fix memory leak in when parsing f-strings in the new parser. Patch by Pablo Galindo \ No newline at end of file diff --git a/Parser/pegen/parse_string.c b/Parser/pegen/parse_string.c index e24ecc58d3aa1..efe82df47658b 100644 --- a/Parser/pegen/parse_string.c +++ b/Parser/pegen/parse_string.c @@ -604,6 +604,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, struct tok_state* tok = PyTokenizer_FromString(str, 1); if (tok == NULL) { + PyMem_RawFree(str); return NULL; } Py_INCREF(p->tok->filename); @@ -629,6 +630,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, result = expr; exit: + PyMem_RawFree(str); _PyPegen_Parser_Free(p2); PyTokenizer_Free(tok); return result; From webhook-mailer at python.org Fri Jun 5 19:52:32 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Fri, 05 Jun 2020 23:52:32 -0000 Subject: [Python-checkins] bpo-40880: Fix invalid read in newline_in_string in pegen.c (#20666) Message-ID: https://github.com/python/cpython/commit/2e6593db0086004a1ca7f7049218ff9573d473c2 commit: 2e6593db0086004a1ca7f7049218ff9573d473c2 branch: master author: Pablo Galindo committer: GitHub date: 2020-06-06T00:52:27+01:00 summary: bpo-40880: Fix invalid read in newline_in_string in pegen.c (#20666) * bpo-40880: Fix invalid read in newline_in_string in pegen.c * Update Parser/pegen/pegen.c Co-authored-by: Lysandros Nikolaou * Add NEWS entry Co-authored-by: Lysandros Nikolaou files: A Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst M Parser/pegen/pegen.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst new file mode 100644 index 0000000000000..ab42f5c205f81 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-06-00-23-19.bpo-40880.fjdzSh.rst @@ -0,0 +1,2 @@ +Fix invalid memory read in the new parser when checking newlines in string +literals. Patch by Pablo Galindo. diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index c55ff7e45c0da..afe75d7f862ee 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -937,8 +937,8 @@ _PyPegen_number_token(Parser *p) static int // bool newline_in_string(Parser *p, const char *cur) { - for (char c = *cur; cur >= p->tok->buf; c = *--cur) { - if (c == '\'' || c == '"') { + for (const char *c = cur; c >= p->tok->buf; c--) { + if (*c == '\'' || *c == '"') { return 1; } } From webhook-mailer at python.org Sat Jun 6 00:21:48 2020 From: webhook-mailer at python.org (Lysandros Nikolaou) Date: Sat, 06 Jun 2020 04:21:48 -0000 Subject: [Python-checkins] Refactor scripts in Tools/peg_generator/scripts (GH-20401) Message-ID: https://github.com/python/cpython/commit/ba6fd87e41dceb01dcdacc57c722aca12cde42a9 commit: ba6fd87e41dceb01dcdacc57c722aca12cde42a9 branch: master author: Lysandros Nikolaou committer: GitHub date: 2020-06-05T21:21:40-07:00 summary: Refactor scripts in Tools/peg_generator/scripts (GH-20401) files: M Modules/_peg_parser.c M Tools/peg_generator/Makefile M Tools/peg_generator/scripts/benchmark.py M Tools/peg_generator/scripts/grammar_grapher.py M Tools/peg_generator/scripts/show_parse.py M Tools/peg_generator/scripts/test_parse_directory.py M Tools/peg_generator/scripts/test_pypi_packages.py diff --git a/Modules/_peg_parser.c b/Modules/_peg_parser.c index b66d5a83a84f6..ca2a3cf7b5fd8 100644 --- a/Modules/_peg_parser.c +++ b/Modules/_peg_parser.c @@ -80,14 +80,15 @@ _Py_compile_string(PyObject *self, PyObject *args, PyObject *kwds) PyObject * _Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) { - static char *keywords[] = {"string", "filename", "mode", "oldparser", NULL}; + static char *keywords[] = {"string", "filename", "mode", "oldparser", "ast", NULL}; char *the_string; char *filename = ""; char *mode_str = "exec"; int oldparser = 0; + int ast = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|ssp", keywords, - &the_string, &filename, &mode_str, &oldparser)) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|sspp", keywords, + &the_string, &filename, &mode_str, &oldparser, &ast)) { return NULL; } @@ -110,7 +111,14 @@ _Py_parse_string(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } - PyObject *result = PyAST_mod2obj(mod); + PyObject *result; + if (ast) { + result = PyAST_mod2obj(mod); + } + else { + Py_INCREF(Py_None); + result = Py_None; + } PyArena_Free(arena); return result; } diff --git a/Tools/peg_generator/Makefile b/Tools/peg_generator/Makefile index e7a190c1bcd13..fb727c048b311 100644 --- a/Tools/peg_generator/Makefile +++ b/Tools/peg_generator/Makefile @@ -70,23 +70,21 @@ stats: peg_extension/parse.c data/xxl.py time: time_compile time_compile: venv data/xxl.py - $(VENVPYTHON) scripts/benchmark.py --parser=pegen --target=xxl compile + $(VENVPYTHON) scripts/benchmark.py --parser=new --target=xxl compile time_parse: venv data/xxl.py - $(VENVPYTHON) scripts/benchmark.py --parser=pegen --target=xxl parse + $(VENVPYTHON) scripts/benchmark.py --parser=new --target=xxl parse time_old: time_old_compile time_old_compile: venv data/xxl.py - $(VENVPYTHON) scripts/benchmark.py --parser=cpython --target=xxl compile + $(VENVPYTHON) scripts/benchmark.py --parser=old --target=xxl compile time_old_parse: venv data/xxl.py - $(VENVPYTHON) scripts/benchmark.py --parser=cpython --target=xxl parse + $(VENVPYTHON) scripts/benchmark.py --parser=old --target=xxl parse time_peg_dir: venv $(VENVPYTHON) scripts/test_parse_directory.py \ - --grammar-file $(GRAMMAR) \ - --tokens-file $(TOKENS) \ -d $(TESTDIR) \ $(TESTFLAGS) \ --exclude "*/failset/*" \ @@ -95,12 +93,8 @@ time_peg_dir: venv time_stdlib: $(CPYTHON) venv $(VENVPYTHON) scripts/test_parse_directory.py \ - --grammar-file $(GRAMMAR) \ - --tokens-file $(TOKENS) \ -d $(CPYTHON) \ $(TESTFLAGS) \ - --exclude "*/test2to3/*" \ - --exclude "*/test2to3/**/*" \ --exclude "*/bad*" \ --exclude "*/lib2to3/tests/data/*" diff --git a/Tools/peg_generator/scripts/benchmark.py b/Tools/peg_generator/scripts/benchmark.py index 71512c22a355b..af356bed78391 100644 --- a/Tools/peg_generator/scripts/benchmark.py +++ b/Tools/peg_generator/scripts/benchmark.py @@ -24,7 +24,7 @@ argparser.add_argument( "--parser", action="store", - choices=["pegen", "cpython"], + choices=["new", "old"], default="pegen", help="Which parser to benchmark (default is pegen)", ) @@ -40,7 +40,12 @@ command_compile = subcommands.add_parser( "compile", help="Benchmark parsing and compiling to bytecode" ) -command_parse = subcommands.add_parser("parse", help="Benchmark parsing and generating an ast.AST") +command_parse = subcommands.add_parser( + "parse", help="Benchmark parsing and generating an ast.AST" +) +command_notree = subcommands.add_parser( + "notree", help="Benchmark parsing and dumping the tree" +) def benchmark(func): @@ -62,7 +67,7 @@ def wrapper(*args): @benchmark def time_compile(source, parser): - if parser == "cpython": + if parser == "old": return _peg_parser.compile_string( source, oldparser=True, @@ -73,32 +78,40 @@ def time_compile(source, parser): @benchmark def time_parse(source, parser): - if parser == "cpython": + if parser == "old": return _peg_parser.parse_string(source, oldparser=True) else: return _peg_parser.parse_string(source) + at benchmark +def time_notree(source, parser): + if parser == "old": + return _peg_parser.parse_string(source, oldparser=True, ast=False) + else: + return _peg_parser.parse_string(source, ast=False) + + def run_benchmark_xxl(subcommand, parser, source): if subcommand == "compile": time_compile(source, parser) elif subcommand == "parse": time_parse(source, parser) + elif subcommand == "notree": + time_notree(source, parser) def run_benchmark_stdlib(subcommand, parser): + modes = {"compile": 2, "parse": 1, "notree": 0} for _ in range(3): parse_directory( "../../Lib", - "../../Grammar/python.gram", - "../../Grammar/Tokens", verbose=False, excluded_files=["*/bad*", "*/lib2to3/tests/data/*",], - skip_actions=False, tree_arg=0, short=True, - mode=2 if subcommand == "compile" else 1, - parser=parser, + mode=modes[subcommand], + oldparser=(parser == "old"), ) diff --git a/Tools/peg_generator/scripts/grammar_grapher.py b/Tools/peg_generator/scripts/grammar_grapher.py index 3aa25466c70d4..4afdbce8f966f 100755 --- a/Tools/peg_generator/scripts/grammar_grapher.py +++ b/Tools/peg_generator/scripts/grammar_grapher.py @@ -42,6 +42,13 @@ ) argparser = argparse.ArgumentParser(prog="graph_grammar", description="Graph a grammar tree",) +argparser.add_argument( + "-s", + "--start", + choices=["exec", "eval", "single"], + default="exec", + help="Choose the grammar's start rule (exec, eval or single)", +) argparser.add_argument("grammar_file", help="The grammar file to graph") @@ -91,19 +98,15 @@ def main() -> None: references[name] = set(references_for_item(rule)) # Flatten the start node if has only a single reference - root_node = "start" - if start := references["start"]: - if len(start) == 1: - root_node = list(start)[0] - del references["start"] + root_node = {"exec": "file", "eval": "eval", "single": "interactive"}[args.start] print("digraph g1 {") print('\toverlap="scale";') # Force twopi to scale the graph to avoid overlaps print(f'\troot="{root_node}";') - print(f"\t{root_node} [color=green, shape=circle]") + print(f"\t{root_node} [color=green, shape=circle];") for name, refs in references.items(): - if refs: # Ignore empty sets - print(f"\t{name} -> {','.join(refs)};") + for ref in refs: + print(f"\t{name} -> {ref};") print("}") diff --git a/Tools/peg_generator/scripts/show_parse.py b/Tools/peg_generator/scripts/show_parse.py index 1c1996f40f74e..b4ee5a1b357f7 100755 --- a/Tools/peg_generator/scripts/show_parse.py +++ b/Tools/peg_generator/scripts/show_parse.py @@ -41,7 +41,13 @@ parser.add_argument( "-d", "--diff", action="store_true", help="show diff between grammar and ast (requires -g)" ) -parser.add_argument("-g", "--grammar-file", help="grammar to use (default: use the ast module)") +parser.add_argument( + "-p", + "--parser", + choices=["new", "old"], + default="new", + help="choose the parser to use" +) parser.add_argument( "-m", "--multiline", @@ -84,19 +90,18 @@ def print_parse(source: str, verbose: bool = False) -> None: def main() -> None: args = parser.parse_args() - if args.diff and not args.grammar_file: - parser.error("-d/--diff requires -g/--grammar-file") + new_parser = args.parser == "new" if args.multiline: sep = "\n" else: sep = " " program = sep.join(args.program) - if args.grammar_file: + if new_parser: tree = _peg_parser.parse_string(program) if args.diff: - a = tree - b = _peg_parser.parse_string(program, oldparser=True) + a = _peg_parser.parse_string(program, oldparser=True) + b = tree diff = diff_trees(a, b, args.verbose) if diff: for line in diff: @@ -104,11 +109,11 @@ def main() -> None: else: print("# Trees are the same") else: - print(f"# Parsed using {args.grammar_file}") + print("# Parsed using the new parser") print(format_tree(tree, args.verbose)) else: tree = _peg_parser.parse_string(program, oldparser=True) - print("# Parse using the old parser") + print("# Parsed using the old parser") print(format_tree(tree, args.verbose)) diff --git a/Tools/peg_generator/scripts/test_parse_directory.py b/Tools/peg_generator/scripts/test_parse_directory.py index e88afe1539ce1..63204ce9dc193 100755 --- a/Tools/peg_generator/scripts/test_parse_directory.py +++ b/Tools/peg_generator/scripts/test_parse_directory.py @@ -11,7 +11,7 @@ from glob import glob from pathlib import PurePath -from typing import List, Optional, Any +from typing import List, Optional, Any, Tuple sys.path.insert(0, os.getcwd()) from pegen.ast_dump import ast_dump @@ -22,13 +22,15 @@ FAIL = "\033[91m" ENDC = "\033[0m" +COMPILE = 2 +PARSE = 1 +NOTREE = 0 + argparser = argparse.ArgumentParser( prog="test_parse_directory", description="Helper program to test directories or files for pegen", ) argparser.add_argument("-d", "--directory", help="Directory path containing files to test") -argparser.add_argument("--grammar-file", help="Grammar file path") -argparser.add_argument("--tokens-file", help="Tokens file path") argparser.add_argument( "-e", "--exclude", action="append", default=[], help="Glob(s) for matching files to exclude" ) @@ -38,9 +40,6 @@ argparser.add_argument( "-v", "--verbose", action="store_true", help="Display detailed errors for failures" ) -argparser.add_argument( - "--skip-actions", action="store_true", help="Suppress code emission for rule actions", -) argparser.add_argument( "-t", "--tree", action="count", help="Compare parse tree to official AST", default=0 ) @@ -113,92 +112,35 @@ def compare_trees( return 1 -def parse_directory( - directory: str, - grammar_file: str, - tokens_file: str, - verbose: bool, - excluded_files: List[str], - skip_actions: bool, - tree_arg: int, - short: bool, - mode: int, - parser: str, -) -> int: - if parser == "cpython" and (tree_arg or mode == 0): - print("Cannot specify tree argument or mode=0 with the cpython parser.", file=sys.stderr) - return 1 - - if not directory: - print("You must specify a directory of files to test.", file=sys.stderr) - return 1 - - if grammar_file and tokens_file: - if not os.path.exists(grammar_file): - print(f"The specified grammar file, {grammar_file}, does not exist.", file=sys.stderr) - return 1 +def parse_file(source: str, file: str, mode: int, oldparser: bool) -> Tuple[Any, float]: + t0 = time.time() + if mode == COMPILE: + result = _peg_parser.compile_string( + source, + filename=file, + oldparser=oldparser, + ) else: - print( - "A grammar file or a tokens file was not provided - attempting to use existing parser from stdlib...\n" + result = _peg_parser.parse_string( + source, + filename=file, + oldparser=oldparser, + ast=(mode == PARSE), ) + t1 = time.time() + return result, t1 - t0 - if tree_arg: - assert mode == 1, "Mode should be 1 (parse), when comparing the generated trees" - # For a given directory, traverse files and attempt to parse each one - # - Output success/failure for each file - errors = 0 - files = [] - trees = {} # Trees to compare (after everything else is done) - total_seconds = 0 +def is_parsing_failure(source: str) -> bool: + try: + _peg_parser.parse_string(source, mode="exec", oldparser=True) + except SyntaxError: + return False + return True - for file in sorted(glob(f"{directory}/**/*.py", recursive=True)): - # Only attempt to parse Python files and files that are not excluded - should_exclude_file = False - for pattern in excluded_files: - if PurePath(file).match(pattern): - should_exclude_file = True - break - - if not should_exclude_file: - with tokenize.open(file) as f: - source = f.read() - try: - t0 = time.time() - if mode == 2: - result = _peg_parser.compile_string( - source, - filename=file, - oldparser=parser == "cpython", - ) - else: - result = _peg_parser.parse_string( - source, - filename=file, - oldparser=parser == "cpython" - ) - t1 = time.time() - total_seconds += (t1 - t0) - if tree_arg: - trees[file] = result - if not short: - report_status(succeeded=True, file=file, verbose=verbose) - except Exception as error: - try: - _peg_parser.parse_string(source, mode="exec", oldparser=True) - except Exception: - if not short: - print(f"File {file} cannot be parsed by either pegen or the ast module.") - else: - report_status( - succeeded=False, file=file, verbose=verbose, error=error, short=short - ) - errors += 1 - files.append(file) - t1 = time.time() +def generate_time_stats(files, total_seconds) -> None: total_files = len(files) - total_bytes = 0 total_lines = 0 for file in files: @@ -217,6 +159,57 @@ def parse_directory( f"or {total_bytes / total_seconds :,.0f} bytes/sec.", ) + +def parse_directory( + directory: str, + verbose: bool, + excluded_files: List[str], + tree_arg: int, + short: bool, + mode: int, + oldparser: bool, +) -> int: + if tree_arg: + assert mode == PARSE, "Mode should be 1 (parse), when comparing the generated trees" + + if oldparser and tree_arg: + print("Cannot specify tree argument with the cpython parser.", file=sys.stderr) + return 1 + + # For a given directory, traverse files and attempt to parse each one + # - Output success/failure for each file + errors = 0 + files = [] + trees = {} # Trees to compare (after everything else is done) + total_seconds = 0 + + for file in sorted(glob(f"{directory}/**/*.py", recursive=True)): + # Only attempt to parse Python files and files that are not excluded + if any(PurePath(file).match(pattern) for pattern in excluded_files): + continue + + with tokenize.open(file) as f: + source = f.read() + + try: + result, dt = parse_file(source, file, mode, oldparser) + total_seconds += dt + if tree_arg: + trees[file] = result + report_status(succeeded=True, file=file, verbose=verbose, short=short) + except SyntaxError as error: + if is_parsing_failure(source): + print(f"File {file} cannot be parsed by either parser.") + else: + report_status( + succeeded=False, file=file, verbose=verbose, error=error, short=short + ) + errors += 1 + files.append(file) + + t1 = time.time() + + generate_time_stats(files, total_seconds) if short: print_memstats() @@ -240,26 +233,20 @@ def parse_directory( def main() -> None: args = argparser.parse_args() directory = args.directory - grammar_file = args.grammar_file - tokens_file = args.tokens_file verbose = args.verbose excluded_files = args.exclude - skip_actions = args.skip_actions tree = args.tree short = args.short mode = 1 if args.tree else 2 sys.exit( parse_directory( directory, - grammar_file, - tokens_file, verbose, excluded_files, - skip_actions, tree, short, mode, - "pegen", + oldparser=False, ) ) diff --git a/Tools/peg_generator/scripts/test_pypi_packages.py b/Tools/peg_generator/scripts/test_pypi_packages.py index 98f77785cdd1c..f014753b3cd23 100755 --- a/Tools/peg_generator/scripts/test_pypi_packages.py +++ b/Tools/peg_generator/scripts/test_pypi_packages.py @@ -57,22 +57,11 @@ def find_dirname(package_name: str) -> str: def run_tests(dirname: str, tree: int) -> int: return test_parse_directory.parse_directory( dirname, - HERE / ".." / ".." / ".." / "Grammar" / "python.gram", - HERE / ".." / ".." / ".." / "Grammar" / "Tokens", verbose=False, - excluded_files=[ - "*/failset/*", - "*/failset/**", - "*/failset/**/*", - "*/test2to3/*", - "*/test2to3/**/*", - "*/bad*", - "*/lib2to3/tests/data/*", - ], - skip_actions=False, + excluded_files=[], tree_arg=tree, short=True, - mode=1, + mode=1 if tree else 0, parser="pegen", ) From webhook-mailer at python.org Sat Jun 6 04:24:50 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 06 Jun 2020 08:24:50 -0000 Subject: [Python-checkins] bpo-40807: Show warnings once from codeop._maybe_compile (GH-20486) Message-ID: https://github.com/python/cpython/commit/c067183605cf84bb1a246635f52827251d0476f8 commit: c067183605cf84bb1a246635f52827251d0476f8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-06T01:24:45-07:00 summary: bpo-40807: Show warnings once from codeop._maybe_compile (GH-20486) * bpo-40807: Show warnings once from codeop._maybe_compile * Move catch_warnings * news Co-authored-by: Terry Jan Reedy (cherry picked from commit 052d3fc0907be253cfd64b2c737a0b0aca586011) Co-authored-by: Cheryl Sabella files: A Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst M Lib/codeop.py M Lib/test/test_codeop.py diff --git a/Lib/codeop.py b/Lib/codeop.py index 3c37f35eb0250..3c2bb6083561e 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -57,6 +57,7 @@ """ import __future__ +import warnings _features = [getattr(__future__, fname) for fname in __future__.all_feature_names] @@ -83,15 +84,18 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError as err: pass - try: - code1 = compiler(source + "\n", filename, symbol) - except SyntaxError as e: - err1 = e - - try: - code2 = compiler(source + "\n\n", filename, symbol) - except SyntaxError as e: - err2 = e + # Suppress warnings after the first compile to avoid duplication. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + code1 = compiler(source + "\n", filename, symbol) + except SyntaxError as e: + err1 = e + + try: + code2 = compiler(source + "\n\n", filename, symbol) + except SyntaxError as e: + err2 = e try: if code: diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 4d52d15fa0fb3..1e57ab9d51e2c 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -294,6 +294,11 @@ def test_filename(self): self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, compile("a = 1\n", "def", 'single').co_filename) + def test_warning(self): + # Test that the warning is only returned once. + with support.check_warnings((".*literal", SyntaxWarning)) as w: + compile_command("0 is 0") + self.assertEqual(len(w.warnings), 1) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst new file mode 100644 index 0000000000000..532b809b77eed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst @@ -0,0 +1,2 @@ +Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). +from from emitting each warning three times. From webhook-mailer at python.org Sat Jun 6 06:09:06 2020 From: webhook-mailer at python.org (Shantanu) Date: Sat, 06 Jun 2020 10:09:06 -0000 Subject: [Python-checkins] bpo-40614: Respect feature version for f-string debug expressions (GH-20196) (GH-20466) Message-ID: https://github.com/python/cpython/commit/f7ed4d4e83f5d9e85e244a1cbc460f26436ab24d commit: f7ed4d4e83f5d9e85e244a1cbc460f26436ab24d branch: 3.8 author: Shantanu committer: GitHub date: 2020-06-06T11:08:48+01:00 summary: bpo-40614: Respect feature version for f-string debug expressions (GH-20196) (GH-20466) Co-authored-by: Lysandros Nikolaou Co-authored-by: Pablo Galindo (cherry picked from commit c116c94ff119485761460f1033cdee425bed0310) files: A Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 486f2aa707e83..869346664499c 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -630,6 +630,12 @@ def test_issue39579_dotted_name_end_col_offset(self): attr_b = tree.body[0].decorator_list[0].value self.assertEqual(attr_b.end_col_offset, 4) + def test_issue40614_feature_version(self): + ast.parse('f"{x=}"', feature_version=(3, 8)) + with self.assertRaises(SyntaxError): + ast.parse('f"{x=}"', feature_version=(3, 7)) + + class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst b/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst new file mode 100644 index 0000000000000..238b98c14a326 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-18-22-41-02.bpo-40614.8j3kmq.rst @@ -0,0 +1 @@ +:func:`ast.parse` will not parse self documenting expressions in f-strings when passed ``feature_version`` is less than ``(3, 8)``. diff --git a/Python/ast.c b/Python/ast.c index f70d48ba3a15d..594879bd0ef0b 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -5202,6 +5202,12 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, /* Check for =, which puts the text value of the expression in expr_text. */ if (**str == '=') { + if (c->c_feature_version < 8) { + ast_error(c, n, + "f-string: self documenting expressions are " + "only supported in Python 3.8 and greater"); + goto error; + } *str += 1; /* Skip over ASCII whitespace. No need to test for end of string From webhook-mailer at python.org Sat Jun 6 07:21:59 2020 From: webhook-mailer at python.org (Ammar Askar) Date: Sat, 06 Jun 2020 11:21:59 -0000 Subject: [Python-checkins] [workflow] Use gcc problem matcher for Ubuntu action build (GH-18567) Message-ID: https://github.com/python/cpython/commit/5552850f8e6ad6bf610c2633c74ed42dacc81b46 commit: 5552850f8e6ad6bf610c2633c74ed42dacc81b46 branch: master author: Ammar Askar committer: GitHub date: 2020-06-06T12:21:46+01:00 summary: [workflow] Use gcc problem matcher for Ubuntu action build (GH-18567) files: A .github/problem-matchers/gcc.json M .github/workflows/build.yml diff --git a/.github/problem-matchers/gcc.json b/.github/problem-matchers/gcc.json new file mode 100644 index 0000000000000..bd5ab6c00a760 --- /dev/null +++ b/.github/problem-matchers/gcc.json @@ -0,0 +1,18 @@ +{ + "__comment": "Taken from vscode-cpptools's Extension/package.json gcc rule", + "problemMatcher": [ + { + "owner": "gcc-problem-matcher", + "pattern": [ + { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6bb52cb6a5daa..5649a6670e75f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -87,6 +87,8 @@ jobs: OPENSSL_VER: 1.1.1f steps: - uses: actions/checkout at v2 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" - name: Install Dependencies run: sudo ./.github/workflows/posix-deps-apt.sh - name: 'Restore OpenSSL build' From webhook-mailer at python.org Sat Jun 6 08:44:20 2020 From: webhook-mailer at python.org (Batuhan Taskaya) Date: Sat, 06 Jun 2020 12:44:20 -0000 Subject: [Python-checkins] bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) Message-ID: https://github.com/python/cpython/commit/68874a8502da440a1dc4746cf73262648b870aee commit: 68874a8502da440a1dc4746cf73262648b870aee branch: master author: Batuhan Taskaya committer: GitHub date: 2020-06-06T05:44:16-07:00 summary: bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index a3b366ec35da1..78e4a5653d4ef 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -668,6 +668,13 @@ def test_issue40614_feature_version(self): with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) + def test_constant_as_name(self): + for constant in "True", "False", "None": + expr = ast.Expression(ast.Name(constant, ast.Load())) + ast.fix_missing_locations(expr) + with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"): + compile(expr, "", "eval") + class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst new file mode 100644 index 0000000000000..8e943a29f337f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst @@ -0,0 +1,2 @@ +Raise :exc:`ValueError` when validating custom AST's where the constants +``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. diff --git a/Python/ast.c b/Python/ast.c index c524b8e34e873..408591f32536f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -21,6 +21,25 @@ static int validate_nonempty_seq(asdl_seq *, const char *, const char *); static int validate_stmt(stmt_ty); static int validate_expr(expr_ty, expr_context_ty); +static int +validate_name(PyObject *name) +{ + assert(PyUnicode_Check(name)); + static const char * const forbidden[] = { + "None", + "True", + "False", + NULL + }; + for (int i = 0; forbidden[i] != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { + PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]); + return 0; + } + } + return 1; +} + static int validate_comprehension(asdl_seq *gens) { @@ -173,6 +192,9 @@ validate_expr(expr_ty exp, expr_context_ty ctx) actual_ctx = exp->v.Starred.ctx; break; case Name_kind: + if (!validate_name(exp->v.Name.id)) { + return 0; + } actual_ctx = exp->v.Name.ctx; break; case List_kind: From webhook-mailer at python.org Sat Jun 6 13:04:51 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 06 Jun 2020 17:04:51 -0000 Subject: [Python-checkins] bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) Message-ID: https://github.com/python/cpython/commit/83a9ba442662c2a030b45955f3dd24ff4b24bb61 commit: 83a9ba442662c2a030b45955f3dd24ff4b24bb61 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-06T10:04:47-07:00 summary: bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) (cherry picked from commit 68874a8502da440a1dc4746cf73262648b870aee) Co-authored-by: Batuhan Taskaya files: A Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst M Lib/test/test_ast.py M Python/ast.c diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 869346664499c..b921f4a5d6826 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -635,6 +635,13 @@ def test_issue40614_feature_version(self): with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) + def test_constant_as_name(self): + for constant in "True", "False", "None": + expr = ast.Expression(ast.Name(constant, ast.Load())) + ast.fix_missing_locations(expr) + with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"): + compile(expr, "", "eval") + class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst new file mode 100644 index 0000000000000..8e943a29f337f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst @@ -0,0 +1,2 @@ +Raise :exc:`ValueError` when validating custom AST's where the constants +``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. diff --git a/Python/ast.c b/Python/ast.c index 594879bd0ef0b..0a999fcca43a8 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -21,6 +21,25 @@ static int validate_nonempty_seq(asdl_seq *, const char *, const char *); static int validate_stmt(stmt_ty); static int validate_expr(expr_ty, expr_context_ty); +static int +validate_name(PyObject *name) +{ + assert(PyUnicode_Check(name)); + static const char * const forbidden[] = { + "None", + "True", + "False", + NULL + }; + for (int i = 0; forbidden[i] != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { + PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]); + return 0; + } + } + return 1; +} + static int validate_comprehension(asdl_seq *gens) { @@ -199,6 +218,9 @@ validate_expr(expr_ty exp, expr_context_ty ctx) actual_ctx = exp->v.Starred.ctx; break; case Name_kind: + if (!validate_name(exp->v.Name.id)) { + return 0; + } actual_ctx = exp->v.Name.ctx; break; case List_kind: From webhook-mailer at python.org Sat Jun 6 15:35:18 2020 From: webhook-mailer at python.org (scoder) Date: Sat, 06 Jun 2020 19:35:18 -0000 Subject: [Python-checkins] bpo-40724: Support setting buffer slots from type specs (GH-20648) Message-ID: https://github.com/python/cpython/commit/f7c4e236429606e1c982cacf24e10fc86ef4462f commit: f7c4e236429606e1c982cacf24e10fc86ef4462f branch: master author: scoder committer: GitHub date: 2020-06-06T21:35:10+02:00 summary: bpo-40724: Support setting buffer slots from type specs (GH-20648) This is not part of the limited API but makes the buffer slots available for type specs. files: A Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst M Include/typeslots.h M Lib/test/test_capi.py M Modules/_testcapimodule.c M Objects/typeslots.inc diff --git a/Include/typeslots.h b/Include/typeslots.h index 0ce6a377dcfbd..64f6fff514449 100644 --- a/Include/typeslots.h +++ b/Include/typeslots.h @@ -1,7 +1,12 @@ /* Do not renumber the file; these numbers are part of the stable ABI. */ +#if defined(Py_LIMITED_API) /* Disabled, see #10181 */ #undef Py_bf_getbuffer #undef Py_bf_releasebuffer +#else +#define Py_bf_getbuffer 1 +#define Py_bf_releasebuffer 2 +#endif #define Py_mp_ass_subscript 3 #define Py_mp_length 4 #define Py_mp_subscript 5 diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 5b8b9f6a86f4b..73e167a0b05a5 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -477,6 +477,11 @@ def test_heaptype_with_weakref(self): self.assertEqual(ref(), inst) self.assertEqual(inst.weakreflist, ref) + def test_heaptype_with_buffer(self): + inst = _testcapi.HeapCTypeWithBuffer() + b = bytes(inst) + self.assertEqual(b, b"1234") + def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self): subclass_instance = _testcapi.HeapCTypeSubclass() type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass) diff --git a/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst b/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst new file mode 100644 index 0000000000000..82793dbf7ad5f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst @@ -0,0 +1 @@ +Allow defining buffer slots in type specs. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 101d54932d913..d6a90b807d026 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6298,6 +6298,47 @@ static PyType_Spec HeapCTypeSubclass_spec = { HeapCTypeSubclass_slots }; +PyDoc_STRVAR(heapctypewithbuffer__doc__, +"Heap type with buffer support.\n\n" +"The buffer is set to [b'1', b'2', b'3', b'4']"); + +typedef struct { + HeapCTypeObject base; + char buffer[4]; +} HeapCTypeWithBufferObject; + +static int +heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) +{ + self->buffer[0] = '1'; + self->buffer[1] = '2'; + self->buffer[2] = '3'; + self->buffer[3] = '4'; + return PyBuffer_FillInfo( + view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); +} + +static int +heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) +{ + assert(view->obj == (void*) self); +} + +static PyType_Slot HeapCTypeWithBuffer_slots[] = { + {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, + {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, + {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBuffer_spec = { + "_testcapi.HeapCTypeWithBuffer", + sizeof(HeapCTypeWithBufferObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithBuffer_slots +}; + PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, "Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" "__class__ is set to plain HeapCTypeSubclass during finalization.\n" @@ -6775,6 +6816,12 @@ PyInit__testcapi(void) } PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); + if (HeapCTypeWithBuffer == NULL) { + return NULL; + } + PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); if (subclass_with_finalizer_bases == NULL) { return NULL; diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index dc750cc0c4197..ffc9bb2e1c771 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -1,6 +1,6 @@ /* Generated by typeslots.py */ -0, -0, +offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer), +offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer), offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), offsetof(PyHeapTypeObject, as_mapping.mp_length), offsetof(PyHeapTypeObject, as_mapping.mp_subscript), From webhook-mailer at python.org Sat Jun 6 15:43:03 2020 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sat, 06 Jun 2020 19:43:03 -0000 Subject: [Python-checkins] Update comments to reflect the current API (GH-20682) Message-ID: https://github.com/python/cpython/commit/0e96c419d7287c3c7f155c9f2de3c61020386256 commit: 0e96c419d7287c3c7f155c9f2de3c61020386256 branch: master author: Raymond Hettinger committer: GitHub date: 2020-06-06T12:42:54-07:00 summary: Update comments to reflect the current API (GH-20682) files: M Lib/collections/__init__.py diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 2acf67289f225..03393f35b11c5 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -760,10 +760,12 @@ def __repr__(self): # set(cp - cq) == sp - sq # set(cp | cq) == sp | sq # set(cp & cq) == sp & sq - # cp.isequal(cq) == (sp == sq) - # cp.issubset(cq) == sp.issubset(sq) - # cp.issuperset(cq) == sp.issuperset(sq) - # cp.isdisjoint(cq) == sp.isdisjoint(sq) + # (cp == cq) == (sp == sq) + # (cp != cq) == (sp != sq) + # (cp <= cq) == (sp <= sq) + # (cp < cq) == (sp < sq) + # (cp >= cq) == (sp >= sq) + # (cp > cq) == (sp > sq) def __add__(self, other): '''Add counts from two counters. From webhook-mailer at python.org Sun Jun 7 08:06:01 2020 From: webhook-mailer at python.org (Hai Shi) Date: Sun, 07 Jun 2020 12:06:01 -0000 Subject: [Python-checkins] bpo-40898: Remove redundant if statements in tp_traverse (GH-20692) Message-ID: https://github.com/python/cpython/commit/47a23fc63fa5df2da8dbc542e78e521d4a7f10c9 commit: 47a23fc63fa5df2da8dbc542e78e521d4a7f10c9 branch: master author: Hai Shi committer: GitHub date: 2020-06-07T21:05:36+09:00 summary: bpo-40898: Remove redundant if statements in tp_traverse (GH-20692) files: M Modules/_functoolsmodule.c M Modules/_io/_iomodule.c M Modules/itertoolsmodule.c M Modules/overlapped.c diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index d158d3bae157b..f1ee23f294fa3 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -484,8 +484,7 @@ static int keyobject_traverse(keyobject *ko, visitproc visit, void *arg) { Py_VISIT(ko->cmp); - if (ko->object) - Py_VISIT(ko->object); + Py_VISIT(ko->object); return 0; } diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index a55e5cad6a392..e430352a48e21 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -623,9 +623,7 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = get_io_state(mod); if (!state->initialized) return 0; - if (state->locale_module != NULL) { - Py_VISIT(state->locale_module); - } + Py_VISIT(state->locale_module); Py_VISIT(state->unsupported_operation); return 0; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 18fcebdf25b46..3f2f7165b171b 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -999,8 +999,7 @@ cycle_dealloc(cycleobject *lz) static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { - if (lz->it) - Py_VISIT(lz->it); + Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index df6282cba819b..eed8fbf039300 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1504,12 +1504,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) } break; case TYPE_READ_FROM: - if(self->read_from.result) { - Py_VISIT(self->read_from.result); - } - if(self->read_from.allocated_buffer) { - Py_VISIT(self->read_from.allocated_buffer); - } + Py_VISIT(self->read_from.result); + Py_VISIT(self->read_from.allocated_buffer); } return 0; } From webhook-mailer at python.org Sun Jun 7 10:57:50 2020 From: webhook-mailer at python.org (Jason R. Coombs) Date: Sun, 07 Jun 2020 14:57:50 -0000 Subject: [Python-checkins] bpo-39791: Support file systems that cannot support non-ascii filenames (skipping tests in that case). (#20681) Message-ID: https://github.com/python/cpython/commit/2efe18bf277dd0f38a1d248ae6bdd30947c26880 commit: 2efe18bf277dd0f38a1d248ae6bdd30947c26880 branch: master author: Jason R. Coombs committer: GitHub date: 2020-06-07T10:57:45-04:00 summary: bpo-39791: Support file systems that cannot support non-ascii filenames (skipping tests in that case). (#20681) files: M Lib/test/test_importlib/fixtures.py M Lib/test/test_importlib/test_main.py diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index b25febb7fe756..2e55d14b9aab9 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -210,6 +210,17 @@ def build_files(file_defs, prefix=pathlib.Path()): f.write(DALS(contents)) +class FileBuilder: + def unicode_filename(self): + try: + import test.support + except ImportError: + # outside CPython, hard-code a unicode snowman + return '?' + return test.support.FS_NONASCII or \ + self.skip("File system does not support non-ascii.") + + def DALS(str): "Dedent and left-strip" return textwrap.dedent(str).lstrip() diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index 7b18c3de16eea..91e501a2eb7cd 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -254,11 +254,16 @@ def test_attr(self): assert self.ep.attr is None -class FileSystem(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): +class FileSystem( + fixtures.OnSysPath, fixtures.SiteDir, fixtures.FileBuilder, + unittest.TestCase): def test_unicode_dir_on_sys_path(self): """ Ensure a Unicode subdirectory of a directory on sys.path does not crash. """ - fixtures.build_files({'?': {}}, prefix=self.site_dir) + fixtures.build_files( + {self.unicode_filename(): {}}, + prefix=self.site_dir, + ) list(distributions()) From webhook-mailer at python.org Sun Jun 7 19:22:40 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Sun, 07 Jun 2020 23:22:40 -0000 Subject: [Python-checkins] bpo-40887: Fix finalize_interp_clear() for free lists (GH-20698) Message-ID: https://github.com/python/cpython/commit/7907f8cbc6923240edb0b5b63adafb871c4c8875 commit: 7907f8cbc6923240edb0b5b63adafb871c4c8875 branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T01:22:36+02:00 summary: bpo-40887: Fix finalize_interp_clear() for free lists (GH-20698) Reorganize code to ensure that free lists are cleared in the right order. Call _PyWarnings_Fini() before _PyList_Fini(). files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 6d2eb1defc884..d730a98d3e5b9 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1250,37 +1250,26 @@ static void finalize_interp_types(PyThreadState *tstate, int is_main_interp) { _PyFrame_Fini(tstate); - _PyTuple_Fini(tstate); - _PyList_Fini(tstate); + _PyAsyncGen_Fini(tstate); + _PyContext_Fini(tstate); + if (is_main_interp) { _PySet_Fini(); - _PyBytes_Fini(); } - - _PyLong_Fini(tstate); - _PyFloat_Fini(tstate); - if (is_main_interp) { _PyDict_Fini(); } + _PyList_Fini(tstate); + _PyTuple_Fini(tstate); _PySlice_Fini(tstate); - _PyWarnings_Fini(tstate->interp); if (is_main_interp) { - _Py_HashRandomization_Fini(); - _PyArg_Fini(); + _PyBytes_Fini(); } - - _PyAsyncGen_Fini(tstate); - _PyContext_Fini(tstate); - - /* Cleanup Unicode implementation */ _PyUnicode_Fini(tstate); - - if (is_main_interp) { - _Py_ClearFileSystemEncoding(); - } + _PyFloat_Fini(tstate); + _PyLong_Fini(tstate); } @@ -1299,19 +1288,20 @@ finalize_interp_clear(PyThreadState *tstate) _PyGC_Fini(tstate); - finalize_interp_types(tstate, is_main_interp); - if (is_main_interp) { - /* XXX Still allocated: - - various static ad-hoc pointers to interned strings - - int and float free list blocks - - whatever various modules and libraries allocate - */ + _Py_HashRandomization_Fini(); + _PyArg_Fini(); + _Py_ClearFileSystemEncoding(); + } - PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + _PyWarnings_Fini(tstate->interp); + if (is_main_interp) { + PyGrammar_RemoveAccelerators(&_PyParser_Grammar); _PyExc_Fini(); } + + finalize_interp_types(tstate, is_main_interp); } From webhook-mailer at python.org Sun Jun 7 19:39:52 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Sun, 07 Jun 2020 23:39:52 -0000 Subject: [Python-checkins] bpo-40881: Fix unicode_release_interned() (GH-20699) Message-ID: https://github.com/python/cpython/commit/c96a61e8163c2d25ed4ac77cf96201fd0bdb945c commit: c96a61e8163c2d25ed4ac77cf96201fd0bdb945c branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T01:39:47+02:00 summary: bpo-40881: Fix unicode_release_interned() (GH-20699) Use Py_SET_REFCNT() in unicode_release_interned(). files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e69bf01251ced..df10888949aba 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15669,13 +15669,13 @@ unicode_release_interned(void) } switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: - Py_REFCNT(s) += 1; + Py_SET_REFCNT(s, Py_REFCNT(s) + 1); #ifdef INTERNED_STATS immortal_size += PyUnicode_GET_LENGTH(s); #endif break; case SSTATE_INTERNED_MORTAL: - Py_REFCNT(s) += 2; + Py_SET_REFCNT(s, Py_REFCNT(s) + 2); #ifdef INTERNED_STATS mortal_size += PyUnicode_GET_LENGTH(s); #endif From webhook-mailer at python.org Sun Jun 7 20:14:55 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jun 2020 00:14:55 -0000 Subject: [Python-checkins] bpo-40887: Don't use finalized free lists (GH-20700) Message-ID: https://github.com/python/cpython/commit/bcb198385dee469d630a184182df9dc1463e2c47 commit: bcb198385dee469d630a184182df9dc1463e2c47 branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T02:14:47+02:00 summary: bpo-40887: Don't use finalized free lists (GH-20700) In debug mode, ensure that free lists are no longer used after being finalized. Set numfree to -1 in finalization functions (eg. _PyList_Fini()), and then check that numfree is not equal to -1 before using a free list (e.g list_dealloc()). files: M Objects/floatobject.c M Objects/frameobject.c M Objects/genobject.c M Objects/listobject.c M Objects/tupleobject.c M Python/context.c diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d72fd21f95faf..65625fe88cad8 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -116,6 +116,10 @@ PyFloat_FromDouble(double fval) struct _Py_float_state *state = &interp->float_state; PyFloatObject *op = state->free_list; if (op != NULL) { +#ifdef Py_DEBUG + // PyFloat_FromDouble() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif state->free_list = (PyFloatObject *) Py_TYPE(op); state->numfree--; } @@ -219,6 +223,10 @@ float_dealloc(PyFloatObject *op) if (PyFloat_CheckExact(op)) { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_float_state *state = &interp->float_state; +#ifdef Py_DEBUG + // float_dealloc() must not be called after _PyFloat_Fini() + assert(state->numfree != -1); +#endif if (state->numfree >= PyFloat_MAXFREELIST) { PyObject_FREE(op); return; @@ -1984,10 +1992,11 @@ void _PyFloat_ClearFreeList(PyThreadState *tstate) { struct _Py_float_state *state = &tstate->interp->float_state; - PyFloatObject *f = state->free_list, *next; - for (; f; f = next) { - next = (PyFloatObject*) Py_TYPE(f); + PyFloatObject *f = state->free_list; + while (f != NULL) { + PyFloatObject *next = (PyFloatObject*) Py_TYPE(f); PyObject_FREE(f); + f = next; } state->free_list = NULL; state->numfree = 0; @@ -1997,6 +2006,10 @@ void _PyFloat_Fini(PyThreadState *tstate) { _PyFloat_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_float_state *state = &tstate->interp->float_state; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 0fe9f2a6666b2..0dad42ee7bff3 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -595,6 +595,10 @@ frame_dealloc(PyFrameObject *f) else { PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_frame_state *state = &interp->frame; +#ifdef Py_DEBUG + // frame_dealloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif if (state->numfree < PyFrame_MAXFREELIST) { ++state->numfree; f->f_back = state->free_list; @@ -790,6 +794,10 @@ frame_alloc(PyCodeObject *code) } } else { +#ifdef Py_DEBUG + // frame_alloc() must not be called after _PyFrame_Fini() + assert(state->numfree != -1); +#endif assert(state->numfree > 0); --state->numfree; f = state->free_list; @@ -1188,6 +1196,10 @@ void _PyFrame_Fini(PyThreadState *tstate) { _PyFrame_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_frame_state *state = &tstate->interp->frame; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ diff --git a/Objects/genobject.c b/Objects/genobject.c index f7dbfd7486419..4207d5326cca1 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1430,6 +1430,11 @@ void _PyAsyncGen_Fini(PyThreadState *tstate) { _PyAsyncGen_ClearFreeLists(tstate); +#ifdef Py_DEBUG + struct _Py_async_gen_state *state = &tstate->interp->async_gen; + state->value_numfree = -1; + state->asend_numfree = -1; +#endif } @@ -1474,6 +1479,10 @@ async_gen_asend_dealloc(PyAsyncGenASend *o) Py_CLEAR(o->ags_sendval); PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_async_gen_state *state = &interp->async_gen; +#ifdef Py_DEBUG + // async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini() + assert(state->asend_numfree != -1); +#endif if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) { assert(PyAsyncGenASend_CheckExact(o)); state->asend_freelist[state->asend_numfree++] = o; @@ -1632,6 +1641,10 @@ async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) PyAsyncGenASend *o; PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_async_gen_state *state = &interp->async_gen; +#ifdef Py_DEBUG + // async_gen_asend_new() must not be called after _PyAsyncGen_Fini() + assert(state->asend_numfree != -1); +#endif if (state->asend_numfree) { state->asend_numfree--; o = state->asend_freelist[state->asend_numfree]; @@ -1667,6 +1680,10 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) Py_CLEAR(o->agw_val); PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_async_gen_state *state = &interp->async_gen; +#ifdef Py_DEBUG + // async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini() + assert(state->value_numfree != -1); +#endif if (state->value_numfree < _PyAsyncGen_MAXFREELIST) { assert(_PyAsyncGenWrappedValue_CheckExact(o)); state->value_freelist[state->value_numfree++] = o; @@ -1737,6 +1754,10 @@ _PyAsyncGenValueWrapperNew(PyObject *val) PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_async_gen_state *state = &interp->async_gen; +#ifdef Py_DEBUG + // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini() + assert(state->value_numfree != -1); +#endif if (state->value_numfree) { state->value_numfree--; o = state->value_freelist[state->value_numfree]; diff --git a/Objects/listobject.c b/Objects/listobject.c index 043256d8adbf5..22cdbe3cfdd41 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -111,6 +111,10 @@ void _PyList_Fini(PyThreadState *tstate) { _PyList_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_list_state *state = &tstate->interp->list; + state->numfree = -1; +#endif } /* Print summary info about the state of the optimized allocator */ @@ -135,6 +139,10 @@ PyList_New(Py_ssize_t size) PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_list_state *state = &interp->list; PyListObject *op; +#ifdef Py_DEBUG + // PyList_New() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif if (state->numfree) { state->numfree--; op = state->free_list[state->numfree]; @@ -330,6 +338,10 @@ list_dealloc(PyListObject *op) } PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_list_state *state = &interp->list; +#ifdef Py_DEBUG + // list_dealloc() must not be called after _PyList_Fini() + assert(state->numfree != -1); +#endif if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) { state->free_list[state->numfree++] = op; } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 951cd1faf7e8f..8bfa0894a79d4 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -54,6 +54,10 @@ tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size) return NULL; } #if PyTuple_MAXSAVESIZE > 0 +#ifdef Py_DEBUG + // tuple_alloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif if (size < PyTuple_MAXSAVESIZE && (op = state->free_list[size]) != NULL) { assert(size != 0); state->free_list[size] = (PyTupleObject *) op->ob_item[0]; @@ -102,6 +106,10 @@ PyTuple_New(Py_ssize_t size) } #if PyTuple_MAXSAVESIZE > 0 if (size == 0) { +#ifdef Py_DEBUG + // PyTuple_New() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif state->free_list[0] = op; ++state->numfree[0]; Py_INCREF(op); /* extra INCREF so that this is never freed */ @@ -227,6 +235,10 @@ tupledealloc(PyTupleObject *op) #if PyTuple_MAXSAVESIZE > 0 PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_tuple_state *state = &interp->tuple; +#ifdef Py_DEBUG + // tupledealloc() must not be called after _PyTuple_Fini() + assert(state->numfree[0] != -1); +#endif if (len < PyTuple_MAXSAVESIZE && state->numfree[len] < PyTuple_MAXFREELIST && Py_IS_TYPE(op, &PyTuple_Type)) @@ -984,6 +996,9 @@ _PyTuple_Fini(PyThreadState *tstate) Py_CLEAR(state->free_list[0]); _PyTuple_ClearFreeList(tstate); +#ifdef Py_DEBUG + state->numfree[0] = -1; +#endif #endif } diff --git a/Python/context.c b/Python/context.c index 3cf8db4c90cdf..dedbca99384c7 100644 --- a/Python/context.c +++ b/Python/context.c @@ -335,6 +335,10 @@ _context_alloc(void) PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_context_state *state = &interp->context; PyContext *ctx; +#ifdef Py_DEBUG + // _context_alloc() must not be called after _PyContext_Fini() + assert(state->numfree != -1); +#endif if (state->numfree) { state->numfree--; ctx = state->freelist; @@ -460,6 +464,10 @@ context_tp_dealloc(PyContext *self) PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_context_state *state = &interp->context; +#ifdef Py_DEBUG + // _context_alloc() must not be called after _PyContext_Fini() + assert(state->numfree != -1); +#endif if (state->numfree < CONTEXT_FREELIST_MAXLEN) { state->numfree++; self->ctx_weakreflist = (PyObject *)state->freelist; @@ -1290,6 +1298,10 @@ _PyContext_Fini(PyThreadState *tstate) { Py_CLEAR(_token_missing); _PyContext_ClearFreeList(tstate); +#ifdef Py_DEBUG + struct _Py_context_state *state = &tstate->interp->context; + state->numfree = -1; +#endif _PyHamt_Fini(); } From webhook-mailer at python.org Sun Jun 7 20:47:42 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Mon, 08 Jun 2020 00:47:42 -0000 Subject: [Python-checkins] bpo-40904: Fix segfault in the new parser with f-string containing yield statements with no value (GH-20701) Message-ID: https://github.com/python/cpython/commit/972ab0327675e695373fc6272d5ac24e187579ad commit: 972ab0327675e695373fc6272d5ac24e187579ad branch: master author: Pablo Galindo committer: GitHub date: 2020-06-08T01:47:37+01:00 summary: bpo-40904: Fix segfault in the new parser with f-string containing yield statements with no value (GH-20701) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst M Lib/test/test_fstring.py M Parser/pegen/parse_string.c diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index ea4e589929e7e..9048e89689df2 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -725,9 +725,11 @@ def test_yield(self): # a function into a generator def fn(y): f'y:{yield y*2}' + f'{yield}' g = fn(4) self.assertEqual(next(g), 8) + self.assertEqual(next(g), None) def test_yield_send(self): def fn(x): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst new file mode 100644 index 0000000000000..09009b18c63a3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-01-08-57.bpo-40904.76qQzo.rst @@ -0,0 +1,2 @@ +Fix possible segfault in the new PEG parser when parsing f-string containing +yield statements with no value (:code:`f"{yield}"`). Patch by Pablo Galindo diff --git a/Parser/pegen/parse_string.c b/Parser/pegen/parse_string.c index efe82df47658b..94241e1965e9a 100644 --- a/Parser/pegen/parse_string.c +++ b/Parser/pegen/parse_string.c @@ -278,6 +278,9 @@ static void fstring_shift_argument(expr_ty parent, arg_ty args, int lineno, int static inline void shift_expr(expr_ty parent, expr_ty n, int line, int col) { + if (n == NULL) { + return; + } if (parent->lineno < n->lineno) { col = 0; } From webhook-mailer at python.org Sun Jun 7 21:00:56 2020 From: webhook-mailer at python.org (Jason R. Coombs) Date: Mon, 08 Jun 2020 01:00:56 -0000 Subject: [Python-checkins] bpo-39791 native hooks for importlib.resources.files (GH-20576) Message-ID: https://github.com/python/cpython/commit/843c27765652e2322011fb3e5d88f4837de38c06 commit: 843c27765652e2322011fb3e5d88f4837de38c06 branch: master author: Jason R. Coombs committer: GitHub date: 2020-06-07T21:00:51-04:00 summary: bpo-39791 native hooks for importlib.resources.files (GH-20576) * Provide native .files support on SourceFileLoader. * Add native importlib.resources.files() support to zipimporter. Remove fallback support. * make regen-all * ?? Added by blurb_it. * Move 'files' into the ResourceReader so it can carry the relevant module name context. * Create 'importlib.readers' module and add FileReader to it. * Add zip reader and rely on it for a TraversableResources object on zipimporter. * Remove TraversableAdapter, no longer needed. * Update blurb. * Replace backslashes with forward slashes. * Incorporate changes from importlib_metadata 2.0, finalizing the interface for extension via get_resource_reader. Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Lib/importlib/readers.py A Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst M Lib/importlib/_bootstrap_external.py M Lib/importlib/_common.py M Lib/importlib/abc.py M Lib/importlib/resources.py M Lib/zipimport.py M Python/importlib_external.h M Python/importlib_zipimport.h diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 25a3f8c0e0934..4f06039f3d23c 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -982,32 +982,10 @@ def get_data(self, path): with _io.FileIO(path, 'r') as file: return file.read() - # ResourceReader ABC API. - @_check_name def get_resource_reader(self, module): - if self.is_package(module): - return self - return None - - def open_resource(self, resource): - path = _path_join(_path_split(self.path)[0], resource) - return _io.FileIO(path, 'r') - - def resource_path(self, resource): - if not self.is_resource(resource): - raise FileNotFoundError - path = _path_join(_path_split(self.path)[0], resource) - return path - - def is_resource(self, name): - if path_sep in name: - return False - path = _path_join(_path_split(self.path)[0], name) - return _path_isfile(path) - - def contents(self): - return iter(_os.listdir(_path_split(self.path)[0])) + from importlib.readers import FileReader + return FileReader(self) class SourceFileLoader(FileLoader, SourceLoader): diff --git a/Lib/importlib/_common.py b/Lib/importlib/_common.py index ba7cbac3c9bfd..b15c59eb9c98a 100644 --- a/Lib/importlib/_common.py +++ b/Lib/importlib/_common.py @@ -1,38 +1,82 @@ import os import pathlib -import zipfile import tempfile import functools import contextlib +import types +import importlib +from typing import Union, Any, Optional +from .abc import ResourceReader -def from_package(package): +Package = Union[types.ModuleType, str] + + +def files(package): """ - Return a Traversable object for the given package. + Get a Traversable resource from a package + """ + return from_package(get_package(package)) + +def normalize_path(path): + # type: (Any) -> str + """Normalize a path by ensuring it is a string. + + If the resulting string contains path separators, an exception is raised. """ - spec = package.__spec__ - return from_traversable_resources(spec) or fallback_resources(spec) + str_path = str(path) + parent, file_name = os.path.split(str_path) + if parent: + raise ValueError('{!r} must be only a file name'.format(path)) + return file_name -def from_traversable_resources(spec): +def get_resource_reader(package): + # type: (types.ModuleType) -> Optional[ResourceReader] """ - If the spec.loader implements TraversableResources, - directly or implicitly, it will have a ``files()`` method. + Return the package's loader if it's a ResourceReader. """ - with contextlib.suppress(AttributeError): - return spec.loader.files() + # We can't use + # a issubclass() check here because apparently abc.'s __subclasscheck__() + # hook wants to create a weak reference to the object, but + # zipimport.zipimporter does not support weak references, resulting in a + # TypeError. That seems terrible. + spec = package.__spec__ + reader = getattr(spec.loader, 'get_resource_reader', None) + if reader is None: + return None + return reader(spec.name) -def fallback_resources(spec): - package_directory = pathlib.Path(spec.origin).parent - try: - archive_path = spec.loader.archive - rel_path = package_directory.relative_to(archive_path) - return zipfile.Path(archive_path, str(rel_path) + '/') - except Exception: - pass - return package_directory +def resolve(cand): + # type: (Package) -> types.ModuleType + return ( + cand if isinstance(cand, types.ModuleType) + else importlib.import_module(cand) + ) + + +def get_package(package): + # type: (Package) -> types.ModuleType + """Take a package name or module object and return the module. + + Raise an exception if the resolved module is not a package. + """ + resolved = resolve(package) + if resolved.__spec__.submodule_search_locations is None: + raise TypeError('{!r} is not a package'.format(package)) + return resolved + + +def from_package(package): + """ + Return a Traversable object for the given package. + + """ + spec = package.__spec__ + reader = spec.loader.get_resource_reader(spec.name) + return reader.files() @contextlib.contextmanager diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index b8a9bb1a21ef7..0b20e7c13f282 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -468,7 +468,7 @@ def resource_path(self, resource): raise FileNotFoundError(resource) def is_resource(self, path): - return self.files().joinpath(path).isfile() + return self.files().joinpath(path).is_file() def contents(self): return (item.name for item in self.files().iterdir()) diff --git a/Lib/importlib/readers.py b/Lib/importlib/readers.py new file mode 100644 index 0000000000000..fb49ebe2b1642 --- /dev/null +++ b/Lib/importlib/readers.py @@ -0,0 +1,30 @@ +import zipfile +import pathlib +from . import abc + + +class FileReader(abc.TraversableResources): + def __init__(self, loader): + self.path = pathlib.Path(loader.path).parent + + def files(self): + return self.path + + +class ZipReader(FileReader): + def __init__(self, loader, module): + _, _, name = module.rpartition('.') + prefix = loader.prefix.replace('\\', '/') + name + '/' + self.path = zipfile.Path(loader.archive, prefix) + + def open_resource(self, resource): + try: + return super().open_resource(resource) + except KeyError as exc: + raise FileNotFoundError(exc.args[0]) + + def is_resource(self, path): + # workaround for `zipfile.Path.is_file` returning true + # for non-existent paths. + target = self.files().joinpath(path) + return target.is_file() and target.exists() diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py index b803a01c91d65..4535619f4f014 100644 --- a/Lib/importlib/resources.py +++ b/Lib/importlib/resources.py @@ -1,15 +1,13 @@ import os -from . import abc as resources_abc from . import _common -from ._common import as_file +from ._common import as_file, files from contextlib import contextmanager, suppress -from importlib import import_module from importlib.abc import ResourceLoader from io import BytesIO, TextIOWrapper from pathlib import Path from types import ModuleType -from typing import ContextManager, Iterable, Optional, Union +from typing import ContextManager, Iterable, Union from typing import cast from typing.io import BinaryIO, TextIO @@ -33,60 +31,11 @@ Resource = Union[str, os.PathLike] -def _resolve(name) -> ModuleType: - """If name is a string, resolve to a module.""" - if hasattr(name, '__spec__'): - return name - return import_module(name) - - -def _get_package(package) -> ModuleType: - """Take a package name or module object and return the module. - - If a name, the module is imported. If the resolved module - object is not a package, raise an exception. - """ - module = _resolve(package) - if module.__spec__.submodule_search_locations is None: - raise TypeError('{!r} is not a package'.format(package)) - return module - - -def _normalize_path(path) -> str: - """Normalize a path by ensuring it is a string. - - If the resulting string contains path separators, an exception is raised. - """ - parent, file_name = os.path.split(path) - if parent: - raise ValueError('{!r} must be only a file name'.format(path)) - return file_name - - -def _get_resource_reader( - package: ModuleType) -> Optional[resources_abc.ResourceReader]: - # Return the package's loader if it's a ResourceReader. We can't use - # a issubclass() check here because apparently abc.'s __subclasscheck__() - # hook wants to create a weak reference to the object, but - # zipimport.zipimporter does not support weak references, resulting in a - # TypeError. That seems terrible. - spec = package.__spec__ - if hasattr(spec.loader, 'get_resource_reader'): - return cast(resources_abc.ResourceReader, - spec.loader.get_resource_reader(spec.name)) - return None - - -def _check_location(package): - if package.__spec__.origin is None or not package.__spec__.has_location: - raise FileNotFoundError(f'Package has no location {package!r}') - - def open_binary(package: Package, resource: Resource) -> BinaryIO: """Return a file-like object opened for binary reading of the resource.""" - resource = _normalize_path(resource) - package = _get_package(package) - reader = _get_resource_reader(package) + resource = _common.normalize_path(resource) + package = _common.get_package(package) + reader = _common.get_resource_reader(package) if reader is not None: return reader.open_resource(resource) absolute_package_path = os.path.abspath( @@ -140,13 +89,6 @@ def read_text(package: Package, return fp.read() -def files(package: Package) -> resources_abc.Traversable: - """ - Get a Traversable resource from a package - """ - return _common.from_package(_get_package(package)) - - def path( package: Package, resource: Resource, ) -> 'ContextManager[Path]': @@ -158,17 +100,18 @@ def path( raised if the file was deleted prior to the context manager exiting). """ - reader = _get_resource_reader(_get_package(package)) + reader = _common.get_resource_reader(_common.get_package(package)) return ( _path_from_reader(reader, resource) if reader else - _common.as_file(files(package).joinpath(_normalize_path(resource))) + _common.as_file( + _common.files(package).joinpath(_common.normalize_path(resource))) ) @contextmanager def _path_from_reader(reader, resource): - norm_resource = _normalize_path(resource) + norm_resource = _common.normalize_path(resource) with suppress(FileNotFoundError): yield Path(reader.resource_path(norm_resource)) return @@ -182,9 +125,9 @@ def is_resource(package: Package, name: str) -> bool: Directories are *not* resources. """ - package = _get_package(package) - _normalize_path(name) - reader = _get_resource_reader(package) + package = _common.get_package(package) + _common.normalize_path(name) + reader = _common.get_resource_reader(package) if reader is not None: return reader.is_resource(name) package_contents = set(contents(package)) @@ -200,8 +143,8 @@ def contents(package: Package) -> Iterable[str]: not considered resources. Use `is_resource()` on each entry returned here to check if it is a resource or not. """ - package = _get_package(package) - reader = _get_resource_reader(package) + package = _common.get_package(package) + reader = _common.get_resource_reader(package) if reader is not None: return reader.contents() # Is the package a namespace package? By definition, namespace packages diff --git a/Lib/zipimport.py b/Lib/zipimport.py index 5ef0a17c2a5ed..080e0c4d986d6 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -280,11 +280,8 @@ def get_resource_reader(self, fullname): return None except ZipImportError: return None - if not _ZipImportResourceReader._registered: - from importlib.abc import ResourceReader - ResourceReader.register(_ZipImportResourceReader) - _ZipImportResourceReader._registered = True - return _ZipImportResourceReader(self, fullname) + from importlib.readers import ZipReader + return ZipReader(self, fullname) def __repr__(self): @@ -719,74 +716,3 @@ def _get_module_code(self, fullname): return code, ispackage, modpath else: raise ZipImportError(f"can't find module {fullname!r}", name=fullname) - - -class _ZipImportResourceReader: - """Private class used to support ZipImport.get_resource_reader(). - - This class is allowed to reference all the innards and private parts of - the zipimporter. - """ - _registered = False - - def __init__(self, zipimporter, fullname): - self.zipimporter = zipimporter - self.fullname = fullname - - def open_resource(self, resource): - fullname_as_path = self.fullname.replace('.', '/') - path = f'{fullname_as_path}/{resource}' - from io import BytesIO - try: - return BytesIO(self.zipimporter.get_data(path)) - except OSError: - raise FileNotFoundError(path) - - def resource_path(self, resource): - # All resources are in the zip file, so there is no path to the file. - # Raising FileNotFoundError tells the higher level API to extract the - # binary data and create a temporary file. - raise FileNotFoundError - - def is_resource(self, name): - # Maybe we could do better, but if we can get the data, it's a - # resource. Otherwise it isn't. - fullname_as_path = self.fullname.replace('.', '/') - path = f'{fullname_as_path}/{name}' - try: - self.zipimporter.get_data(path) - except OSError: - return False - return True - - def contents(self): - # This is a bit convoluted, because fullname will be a module path, - # but _files is a list of file names relative to the top of the - # archive's namespace. We want to compare file paths to find all the - # names of things inside the module represented by fullname. So we - # turn the module path of fullname into a file path relative to the - # top of the archive, and then we iterate through _files looking for - # names inside that "directory". - from pathlib import Path - fullname_path = Path(self.zipimporter.get_filename(self.fullname)) - relative_path = fullname_path.relative_to(self.zipimporter.archive) - # Don't forget that fullname names a package, so its path will include - # __init__.py, which we want to ignore. - assert relative_path.name == '__init__.py' - package_path = relative_path.parent - subdirs_seen = set() - for filename in self.zipimporter._files: - try: - relative = Path(filename).relative_to(package_path) - except ValueError: - continue - # If the path of the file (which is relative to the top of the zip - # namespace), relative to the package given when the resource - # reader was created, has a parent, then it's a name in a - # subdirectory and thus we skip it. - parent_name = relative.parent.name - if len(parent_name) == 0: - yield relative.name - elif parent_name not in subdirs_seen: - subdirs_seen.add(parent_name) - yield parent_name diff --git a/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst b/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst new file mode 100644 index 0000000000000..61753a57ca8b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-02-02-16-02.bpo-39791.StCJlA.rst @@ -0,0 +1 @@ +Built-in loaders (SourceFileLoader and ZipImporter) now supply ``TraversableResources`` implementations for ``ResourceReader``, and the fallback function has been removed. diff --git a/Python/importlib_external.h b/Python/importlib_external.h index dd237428867ba..4d08e01b138c3 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1396,15 +1396,13 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,29,3,0,0,115,14,0,0,0,8,2,8,8,8, 14,8,10,8,7,8,10,14,8,114,221,0,0,0,99,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,0,0,0,0,115,124,0,0,0,101,0,90,1, + 0,0,0,0,0,0,0,115,92,0,0,0,101,0,90,1, 100,0,90,2,100,1,90,3,100,2,100,3,132,0,90,4, 100,4,100,5,132,0,90,5,100,6,100,7,132,0,90,6, 101,7,135,0,102,1,100,8,100,9,132,8,131,1,90,8, 101,7,100,10,100,11,132,0,131,1,90,9,100,12,100,13, 132,0,90,10,101,7,100,14,100,15,132,0,131,1,90,11, - 100,16,100,17,132,0,90,12,100,18,100,19,132,0,90,13, - 100,20,100,21,132,0,90,14,100,22,100,23,132,0,90,15, - 135,0,4,0,90,16,83,0,41,24,218,10,70,105,108,101, + 135,0,4,0,90,12,83,0,41,16,218,10,70,105,108,101, 76,111,97,100,101,114,122,103,66,97,115,101,32,102,105,108, 101,32,108,111,97,100,101,114,32,99,108,97,115,115,32,119, 104,105,99,104,32,105,109,112,108,101,109,101,110,116,115,32, @@ -1489,72 +1487,27 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,208,3,0,0,115,10,0,0,0,0,2,14,1,16, 1,40,2,14,1,122,19,70,105,108,101,76,111,97,100,101, 114,46,103,101,116,95,100,97,116,97,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,18,0,0,0,124,0,160,0,124,1,161,1, - 114,14,124,0,83,0,100,0,83,0,114,109,0,0,0,41, - 1,114,182,0,0,0,169,2,114,118,0,0,0,114,216,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,19,103,101,116,95,114,101,115,111,117,114,99,101,95, - 114,101,97,100,101,114,219,3,0,0,115,6,0,0,0,0, - 2,10,1,4,1,122,30,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,114,101,115,111,117,114,99,101,95,114, - 101,97,100,101,114,99,2,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,32, - 0,0,0,116,0,116,1,124,0,106,2,131,1,100,1,25, - 0,124,1,131,2,125,2,116,3,160,4,124,2,100,2,161, - 2,83,0,41,3,78,114,73,0,0,0,114,251,0,0,0, - 41,5,114,38,0,0,0,114,47,0,0,0,114,44,0,0, - 0,114,64,0,0,0,114,65,0,0,0,169,3,114,118,0, - 0,0,90,8,114,101,115,111,117,114,99,101,114,44,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 218,13,111,112,101,110,95,114,101,115,111,117,114,99,101,225, - 3,0,0,115,4,0,0,0,0,1,20,1,122,24,70,105, - 108,101,76,111,97,100,101,114,46,111,112,101,110,95,114,101, - 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, - 38,0,0,0,124,0,160,0,124,1,161,1,115,14,116,1, - 130,1,116,2,116,3,124,0,106,4,131,1,100,1,25,0, - 124,1,131,2,125,2,124,2,83,0,169,2,78,114,73,0, - 0,0,41,5,218,11,105,115,95,114,101,115,111,117,114,99, - 101,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, - 114,114,111,114,114,38,0,0,0,114,47,0,0,0,114,44, - 0,0,0,114,255,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,218,13,114,101,115,111,117,114,99, - 101,95,112,97,116,104,229,3,0,0,115,8,0,0,0,0, - 1,10,1,4,1,20,1,122,24,70,105,108,101,76,111,97, - 100,101,114,46,114,101,115,111,117,114,99,101,95,112,97,116, - 104,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,40,0,0,0,116, - 0,124,1,118,0,114,12,100,1,83,0,116,1,116,2,124, - 0,106,3,131,1,100,2,25,0,124,1,131,2,125,2,116, - 4,124,2,131,1,83,0,41,3,78,70,114,73,0,0,0, - 41,5,114,35,0,0,0,114,38,0,0,0,114,47,0,0, - 0,114,44,0,0,0,114,54,0,0,0,169,3,114,118,0, - 0,0,114,116,0,0,0,114,44,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,2,1,0,0, - 235,3,0,0,115,8,0,0,0,0,1,8,1,4,1,20, - 1,122,22,70,105,108,101,76,111,97,100,101,114,46,105,115, - 95,114,101,115,111,117,114,99,101,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,5,0,0,0,67,0, - 0,0,115,24,0,0,0,116,0,116,1,160,2,116,3,124, - 0,106,4,131,1,100,1,25,0,161,1,131,1,83,0,114, - 1,1,0,0,41,5,218,4,105,116,101,114,114,4,0,0, - 0,218,7,108,105,115,116,100,105,114,114,47,0,0,0,114, - 44,0,0,0,114,246,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,218,8,99,111,110,116,101,110, - 116,115,241,3,0,0,115,2,0,0,0,0,1,122,19,70, - 105,108,101,76,111,97,100,101,114,46,99,111,110,116,101,110, - 116,115,41,17,114,125,0,0,0,114,124,0,0,0,114,126, - 0,0,0,114,127,0,0,0,114,209,0,0,0,114,243,0, - 0,0,114,247,0,0,0,114,136,0,0,0,114,220,0,0, - 0,114,179,0,0,0,114,227,0,0,0,114,254,0,0,0, - 114,0,1,0,0,114,4,1,0,0,114,2,1,0,0,114, - 8,1,0,0,90,13,95,95,99,108,97,115,115,99,101,108, - 108,95,95,114,5,0,0,0,114,5,0,0,0,114,249,0, - 0,0,114,8,0,0,0,114,239,0,0,0,173,3,0,0, - 115,30,0,0,0,8,2,4,3,8,6,8,4,8,3,2, - 1,14,11,2,1,10,4,8,11,2,1,10,5,8,4,8, - 6,8,6,114,239,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, + 0,0,0,115,20,0,0,0,100,1,100,2,108,0,109,1, + 125,2,1,0,124,2,124,0,131,1,83,0,41,3,78,114, + 73,0,0,0,41,1,218,10,70,105,108,101,82,101,97,100, + 101,114,41,2,90,17,105,109,112,111,114,116,108,105,98,46, + 114,101,97,100,101,114,115,114,253,0,0,0,41,3,114,118, + 0,0,0,114,216,0,0,0,114,253,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,218,19,103,101, + 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, + 114,217,3,0,0,115,4,0,0,0,0,2,12,1,122,30, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,114, + 101,115,111,117,114,99,101,95,114,101,97,100,101,114,41,13, + 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, + 127,0,0,0,114,209,0,0,0,114,243,0,0,0,114,247, + 0,0,0,114,136,0,0,0,114,220,0,0,0,114,179,0, + 0,0,114,227,0,0,0,114,254,0,0,0,90,13,95,95, + 99,108,97,115,115,99,101,108,108,95,95,114,5,0,0,0, + 114,5,0,0,0,114,249,0,0,0,114,8,0,0,0,114, + 239,0,0,0,173,3,0,0,115,22,0,0,0,8,2,4, + 3,8,6,8,4,8,3,2,1,14,11,2,1,10,4,8, + 9,2,1,114,239,0,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, 0,115,46,0,0,0,101,0,90,1,100,0,90,2,100,1, 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, @@ -1574,7 +1527,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 49,0,0,0,218,8,115,116,95,109,116,105,109,101,90,7, 115,116,95,115,105,122,101,41,3,114,118,0,0,0,114,44, 0,0,0,114,238,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,224,0,0,0,249,3,0,0, + 0,0,114,8,0,0,0,114,224,0,0,0,227,3,0,0, 115,4,0,0,0,0,2,8,1,122,27,83,111,117,114,99, 101,70,105,108,101,76,111,97,100,101,114,46,112,97,116,104, 95,115,116,97,116,115,99,4,0,0,0,0,0,0,0,0, @@ -1585,10 +1538,10 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 225,0,0,0,41,5,114,118,0,0,0,114,107,0,0,0, 114,106,0,0,0,114,26,0,0,0,114,52,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,226, - 0,0,0,254,3,0,0,115,4,0,0,0,0,2,8,1, + 0,0,0,232,3,0,0,115,4,0,0,0,0,2,8,1, 122,32,83,111,117,114,99,101,70,105,108,101,76,111,97,100, 101,114,46,95,99,97,99,104,101,95,98,121,116,101,99,111, - 100,101,114,60,0,0,0,114,11,1,0,0,99,3,0,0, + 100,101,114,60,0,0,0,114,1,1,0,0,99,3,0,0, 0,0,0,0,0,1,0,0,0,9,0,0,0,11,0,0, 0,67,0,0,0,115,252,0,0,0,116,0,124,1,131,1, 92,2,125,4,125,5,103,0,125,6,124,4,114,52,116,1, @@ -1616,11 +1569,11 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,90,5,109,107,100,105,114,218,15,70,105,108,101,69,120, 105,115,116,115,69,114,114,111,114,114,50,0,0,0,114,134, 0,0,0,114,149,0,0,0,114,69,0,0,0,41,9,114, - 118,0,0,0,114,44,0,0,0,114,26,0,0,0,114,12, + 118,0,0,0,114,44,0,0,0,114,26,0,0,0,114,2, 1,0,0,218,6,112,97,114,101,110,116,114,96,0,0,0, 114,37,0,0,0,114,33,0,0,0,114,228,0,0,0,114, 5,0,0,0,114,5,0,0,0,114,8,0,0,0,114,225, - 0,0,0,3,4,0,0,115,46,0,0,0,0,2,12,1, + 0,0,0,237,3,0,0,115,46,0,0,0,0,2,12,1, 4,2,12,1,12,1,12,2,12,1,10,1,2,1,14,1, 12,2,8,1,14,3,6,1,4,255,4,2,28,1,2,1, 12,1,16,1,16,2,8,1,2,255,122,25,83,111,117,114, @@ -1629,8 +1582,8 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,114,126,0,0,0,114,127,0,0,0,114,224,0,0, 0,114,226,0,0,0,114,225,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 9,1,0,0,245,3,0,0,115,8,0,0,0,8,2,4, - 2,8,5,8,5,114,9,1,0,0,99,0,0,0,0,0, + 255,0,0,0,223,3,0,0,115,8,0,0,0,8,2,4, + 2,8,5,8,5,114,255,0,0,0,99,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, 0,0,0,115,32,0,0,0,101,0,90,1,100,0,90,2, 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, @@ -1651,7 +1604,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 114,235,0,0,0,41,5,114,118,0,0,0,114,139,0,0, 0,114,44,0,0,0,114,26,0,0,0,114,151,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 213,0,0,0,38,4,0,0,115,22,0,0,0,0,1,10, + 213,0,0,0,16,4,0,0,115,22,0,0,0,0,1,10, 1,10,4,2,1,2,254,6,4,12,1,2,1,14,1,2, 1,2,253,122,29,83,111,117,114,99,101,108,101,115,115,70, 105,108,101,76,111,97,100,101,114,46,103,101,116,95,99,111, @@ -1661,15 +1614,15 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 111,110,101,32,97,115,32,116,104,101,114,101,32,105,115,32, 110,111,32,115,111,117,114,99,101,32,99,111,100,101,46,78, 114,5,0,0,0,114,219,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,229,0,0,0,54,4, + 5,0,0,0,114,8,0,0,0,114,229,0,0,0,32,4, 0,0,115,2,0,0,0,0,2,122,31,83,111,117,114,99, 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, 103,101,116,95,115,111,117,114,99,101,78,41,6,114,125,0, 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, 0,114,213,0,0,0,114,229,0,0,0,114,5,0,0,0, 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 15,1,0,0,34,4,0,0,115,6,0,0,0,8,2,4, - 2,8,16,114,15,1,0,0,99,0,0,0,0,0,0,0, + 5,1,0,0,12,4,0,0,115,6,0,0,0,8,2,4, + 2,8,16,114,5,1,0,0,99,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, 0,115,92,0,0,0,101,0,90,1,100,0,90,2,100,1, 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, @@ -1687,1049 +1640,1051 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, 95,1,100,0,83,0,114,109,0,0,0,114,159,0,0,0, - 114,5,1,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,209,0,0,0,71,4,0,0,115,4,0, - 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,0, - 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, - 106,1,124,1,106,1,107,2,83,0,114,109,0,0,0,114, - 240,0,0,0,114,242,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,243,0,0,0,75,4,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,0, - 124,0,106,2,131,1,65,0,83,0,114,109,0,0,0,114, - 244,0,0,0,114,246,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,247,0,0,0,79,4,0, - 0,115,2,0,0,0,0,1,122,28,69,120,116,101,110,115, + 41,3,114,118,0,0,0,114,116,0,0,0,114,44,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 114,209,0,0,0,49,4,0,0,115,4,0,0,0,0,1, + 6,1,122,28,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,95,95,105,110,105,116,95,95, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,24,0,0,0,124,0, + 106,0,124,1,106,0,107,2,111,22,124,0,106,1,124,1, + 106,1,107,2,83,0,114,109,0,0,0,114,240,0,0,0, + 114,242,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,243,0,0,0,53,4,0,0,115,6,0, + 0,0,0,1,12,1,10,255,122,26,69,120,116,101,110,115, 105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,95, - 104,97,115,104,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,115, - 36,0,0,0,116,0,160,1,116,2,106,3,124,1,161,2, - 125,2,116,0,160,4,100,1,124,1,106,5,124,0,106,6, - 161,3,1,0,124,2,83,0,41,2,122,38,67,114,101,97, - 116,101,32,97,110,32,117,110,105,116,105,97,108,105,122,101, - 100,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, - 108,101,122,38,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,32,123,33,114,125,32,108,111,97,100,101,100, - 32,102,114,111,109,32,123,33,114,125,41,7,114,134,0,0, - 0,114,214,0,0,0,114,163,0,0,0,90,14,99,114,101, - 97,116,101,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,116,0,0,0,114,44,0,0,0,41,3,114,118,0,0, - 0,114,187,0,0,0,114,216,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,212,0,0,0,82, - 4,0,0,115,14,0,0,0,0,2,4,1,6,255,4,2, - 6,1,8,255,4,2,122,33,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,99,114,101,97, - 116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,5,0,0,0,67,0, - 0,0,115,36,0,0,0,116,0,160,1,116,2,106,3,124, - 1,161,2,1,0,116,0,160,4,100,1,124,0,106,5,124, - 0,106,6,161,3,1,0,100,2,83,0,41,3,122,30,73, - 110,105,116,105,97,108,105,122,101,32,97,110,32,101,120,116, - 101,110,115,105,111,110,32,109,111,100,117,108,101,122,40,101, - 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,32, - 123,33,114,125,32,101,120,101,99,117,116,101,100,32,102,114, - 111,109,32,123,33,114,125,78,41,7,114,134,0,0,0,114, - 214,0,0,0,114,163,0,0,0,90,12,101,120,101,99,95, + 101,113,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,20,0, + 0,0,116,0,124,0,106,1,131,1,116,0,124,0,106,2, + 131,1,65,0,83,0,114,109,0,0,0,114,244,0,0,0, + 114,246,0,0,0,114,5,0,0,0,114,5,0,0,0,114, + 8,0,0,0,114,247,0,0,0,57,4,0,0,115,2,0, + 0,0,0,1,122,28,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,95,95,104,97,115,104, + 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,5,0,0,0,67,0,0,0,115,36,0,0,0, + 116,0,160,1,116,2,106,3,124,1,161,2,125,2,116,0, + 160,4,100,1,124,1,106,5,124,0,106,6,161,3,1,0, + 124,2,83,0,41,2,122,38,67,114,101,97,116,101,32,97, + 110,32,117,110,105,116,105,97,108,105,122,101,100,32,101,120, + 116,101,110,115,105,111,110,32,109,111,100,117,108,101,122,38, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,123,33,114,125,32,108,111,97,100,101,100,32,102,114,111, + 109,32,123,33,114,125,41,7,114,134,0,0,0,114,214,0, + 0,0,114,163,0,0,0,90,14,99,114,101,97,116,101,95, 100,121,110,97,109,105,99,114,149,0,0,0,114,116,0,0, - 0,114,44,0,0,0,114,253,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,217,0,0,0,90, - 4,0,0,115,8,0,0,0,0,2,14,1,6,1,8,255, - 122,31,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,46,101,120,101,99,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,4,0,0,0,3,0,0,0,115,36,0,0,0,116, - 0,124,0,106,1,131,1,100,1,25,0,137,0,116,2,135, - 0,102,1,100,2,100,3,132,8,116,3,68,0,131,1,131, - 1,83,0,41,4,122,49,82,101,116,117,114,110,32,84,114, - 117,101,32,105,102,32,116,104,101,32,101,120,116,101,110,115, - 105,111,110,32,109,111,100,117,108,101,32,105,115,32,97,32, - 112,97,99,107,97,103,101,46,114,39,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, - 0,0,51,0,0,0,115,26,0,0,0,124,0,93,18,125, - 1,136,0,100,0,124,1,23,0,107,2,86,0,1,0,113, - 2,100,1,83,0,41,2,114,209,0,0,0,78,114,5,0, - 0,0,169,2,114,32,0,0,0,218,6,115,117,102,102,105, - 120,169,1,90,9,102,105,108,101,95,110,97,109,101,114,5, - 0,0,0,114,8,0,0,0,218,9,60,103,101,110,101,120, - 112,114,62,99,4,0,0,115,4,0,0,0,4,1,2,255, - 122,49,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,46,105,115,95,112,97,99,107,97,103,101, - 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, - 112,114,62,41,4,114,47,0,0,0,114,44,0,0,0,218, - 3,97,110,121,218,18,69,88,84,69,78,83,73,79,78,95, - 83,85,70,70,73,88,69,83,114,219,0,0,0,114,5,0, - 0,0,114,18,1,0,0,114,8,0,0,0,114,182,0,0, - 0,96,4,0,0,115,8,0,0,0,0,2,14,1,12,1, - 2,255,122,30,69,120,116,101,110,115,105,111,110,70,105,108, - 101,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97, - 103,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,122,63,82,101,116,117,114,110,32,78, - 111,110,101,32,97,115,32,97,110,32,101,120,116,101,110,115, - 105,111,110,32,109,111,100,117,108,101,32,99,97,110,110,111, - 116,32,99,114,101,97,116,101,32,97,32,99,111,100,101,32, - 111,98,106,101,99,116,46,78,114,5,0,0,0,114,219,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,213,0,0,0,102,4,0,0,115,2,0,0,0,0, - 2,122,28,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,99,111,100,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,122,53,82,101,116,117,114,110,32,78,111,110,101, - 32,97,115,32,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,115,32,104,97,118,101,32,110,111,32,115,111, - 117,114,99,101,32,99,111,100,101,46,78,114,5,0,0,0, + 0,114,44,0,0,0,41,3,114,118,0,0,0,114,187,0, + 0,0,114,216,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,114,212,0,0,0,60,4,0,0,115, + 14,0,0,0,0,2,4,1,6,255,4,2,6,1,8,255, + 4,2,122,33,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,99,114,101,97,116,101,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,5,0,0,0,67,0,0,0,115,36, + 0,0,0,116,0,160,1,116,2,106,3,124,1,161,2,1, + 0,116,0,160,4,100,1,124,0,106,5,124,0,106,6,161, + 3,1,0,100,2,83,0,41,3,122,30,73,110,105,116,105, + 97,108,105,122,101,32,97,110,32,101,120,116,101,110,115,105, + 111,110,32,109,111,100,117,108,101,122,40,101,120,116,101,110, + 115,105,111,110,32,109,111,100,117,108,101,32,123,33,114,125, + 32,101,120,101,99,117,116,101,100,32,102,114,111,109,32,123, + 33,114,125,78,41,7,114,134,0,0,0,114,214,0,0,0, + 114,163,0,0,0,90,12,101,120,101,99,95,100,121,110,97, + 109,105,99,114,149,0,0,0,114,116,0,0,0,114,44,0, + 0,0,169,2,114,118,0,0,0,114,216,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,114,217,0, + 0,0,68,4,0,0,115,8,0,0,0,0,2,14,1,6, + 1,8,255,122,31,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,101,120,101,99,95,109,111, + 100,117,108,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,4,0,0,0,3,0,0,0,115,36,0, + 0,0,116,0,124,0,106,1,131,1,100,1,25,0,137,0, + 116,2,135,0,102,1,100,2,100,3,132,8,116,3,68,0, + 131,1,131,1,83,0,41,4,122,49,82,101,116,117,114,110, + 32,84,114,117,101,32,105,102,32,116,104,101,32,101,120,116, + 101,110,115,105,111,110,32,109,111,100,117,108,101,32,105,115, + 32,97,32,112,97,99,107,97,103,101,46,114,39,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,4,0,0,0,51,0,0,0,115,26,0,0,0,124,0, + 93,18,125,1,136,0,100,0,124,1,23,0,107,2,86,0, + 1,0,113,2,100,1,83,0,41,2,114,209,0,0,0,78, + 114,5,0,0,0,169,2,114,32,0,0,0,218,6,115,117, + 102,102,105,120,169,1,90,9,102,105,108,101,95,110,97,109, + 101,114,5,0,0,0,114,8,0,0,0,218,9,60,103,101, + 110,101,120,112,114,62,77,4,0,0,115,4,0,0,0,4, + 1,2,255,122,49,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, + 97,103,101,46,60,108,111,99,97,108,115,62,46,60,103,101, + 110,101,120,112,114,62,41,4,114,47,0,0,0,114,44,0, + 0,0,218,3,97,110,121,218,18,69,88,84,69,78,83,73, + 79,78,95,83,85,70,70,73,88,69,83,114,219,0,0,0, + 114,5,0,0,0,114,9,1,0,0,114,8,0,0,0,114, + 182,0,0,0,74,4,0,0,115,8,0,0,0,0,2,14, + 1,12,1,2,255,122,30,69,120,116,101,110,115,105,111,110, + 70,105,108,101,76,111,97,100,101,114,46,105,115,95,112,97, + 99,107,97,103,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,122,63,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,97,110,32,101,120,116, + 101,110,115,105,111,110,32,109,111,100,117,108,101,32,99,97, + 110,110,111,116,32,99,114,101,97,116,101,32,97,32,99,111, + 100,101,32,111,98,106,101,99,116,46,78,114,5,0,0,0, 114,219,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,229,0,0,0,106,4,0,0,115,2,0, - 0,0,0,2,122,30,69,120,116,101,110,115,105,111,110,70, - 105,108,101,76,111,97,100,101,114,46,103,101,116,95,115,111, - 117,114,99,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,115,6,0, - 0,0,124,0,106,0,83,0,114,250,0,0,0,114,48,0, - 0,0,114,219,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,179,0,0,0,110,4,0,0,115, - 2,0,0,0,0,3,122,32,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, - 102,105,108,101,110,97,109,101,78,41,14,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, - 209,0,0,0,114,243,0,0,0,114,247,0,0,0,114,212, - 0,0,0,114,217,0,0,0,114,182,0,0,0,114,213,0, - 0,0,114,229,0,0,0,114,136,0,0,0,114,179,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,114,252,0,0,0,63,4,0,0,115,22, - 0,0,0,8,2,4,6,8,4,8,4,8,3,8,8,8, - 6,8,6,8,4,8,4,2,1,114,252,0,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,64,0,0,0,115,104,0,0,0,101,0,90,1, - 100,0,90,2,100,1,90,3,100,2,100,3,132,0,90,4, - 100,4,100,5,132,0,90,5,100,6,100,7,132,0,90,6, - 100,8,100,9,132,0,90,7,100,10,100,11,132,0,90,8, - 100,12,100,13,132,0,90,9,100,14,100,15,132,0,90,10, - 100,16,100,17,132,0,90,11,100,18,100,19,132,0,90,12, - 100,20,100,21,132,0,90,13,100,22,100,23,132,0,90,14, - 100,24,83,0,41,25,218,14,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,97,38,1,0,0,82,101,112,114,101, - 115,101,110,116,115,32,97,32,110,97,109,101,115,112,97,99, - 101,32,112,97,99,107,97,103,101,39,115,32,112,97,116,104, - 46,32,32,73,116,32,117,115,101,115,32,116,104,101,32,109, - 111,100,117,108,101,32,110,97,109,101,10,32,32,32,32,116, - 111,32,102,105,110,100,32,105,116,115,32,112,97,114,101,110, - 116,32,109,111,100,117,108,101,44,32,97,110,100,32,102,114, - 111,109,32,116,104,101,114,101,32,105,116,32,108,111,111,107, - 115,32,117,112,32,116,104,101,32,112,97,114,101,110,116,39, - 115,10,32,32,32,32,95,95,112,97,116,104,95,95,46,32, - 32,87,104,101,110,32,116,104,105,115,32,99,104,97,110,103, - 101,115,44,32,116,104,101,32,109,111,100,117,108,101,39,115, - 32,111,119,110,32,112,97,116,104,32,105,115,32,114,101,99, - 111,109,112,117,116,101,100,44,10,32,32,32,32,117,115,105, - 110,103,32,112,97,116,104,95,102,105,110,100,101,114,46,32, - 32,70,111,114,32,116,111,112,45,108,101,118,101,108,32,109, - 111,100,117,108,101,115,44,32,116,104,101,32,112,97,114,101, - 110,116,32,109,111,100,117,108,101,39,115,32,112,97,116,104, - 10,32,32,32,32,105,115,32,115,121,115,46,112,97,116,104, - 46,99,4,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,3,0,0,0,67,0,0,0,115,36,0,0,0,124, - 1,124,0,95,0,124,2,124,0,95,1,116,2,124,0,160, - 3,161,0,131,1,124,0,95,4,124,3,124,0,95,5,100, - 0,83,0,114,109,0,0,0,41,6,218,5,95,110,97,109, - 101,218,5,95,112,97,116,104,114,111,0,0,0,218,16,95, - 103,101,116,95,112,97,114,101,110,116,95,112,97,116,104,218, - 17,95,108,97,115,116,95,112,97,114,101,110,116,95,112,97, - 116,104,218,12,95,112,97,116,104,95,102,105,110,100,101,114, - 169,4,114,118,0,0,0,114,116,0,0,0,114,44,0,0, - 0,90,11,112,97,116,104,95,102,105,110,100,101,114,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,209,0, - 0,0,123,4,0,0,115,8,0,0,0,0,1,6,1,6, - 1,14,1,122,23,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, - 0,67,0,0,0,115,38,0,0,0,124,0,106,0,160,1, - 100,1,161,1,92,3,125,1,125,2,125,3,124,2,100,2, - 107,2,114,30,100,3,83,0,124,1,100,4,102,2,83,0, - 41,5,122,62,82,101,116,117,114,110,115,32,97,32,116,117, - 112,108,101,32,111,102,32,40,112,97,114,101,110,116,45,109, - 111,100,117,108,101,45,110,97,109,101,44,32,112,97,114,101, - 110,116,45,112,97,116,104,45,97,116,116,114,45,110,97,109, - 101,41,114,71,0,0,0,114,40,0,0,0,41,2,114,1, - 0,0,0,114,44,0,0,0,90,8,95,95,112,97,116,104, - 95,95,41,2,114,23,1,0,0,114,41,0,0,0,41,4, - 114,118,0,0,0,114,14,1,0,0,218,3,100,111,116,90, - 2,109,101,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,23,95,102,105,110,100,95,112,97,114,101,110,116, - 95,112,97,116,104,95,110,97,109,101,115,129,4,0,0,115, - 8,0,0,0,0,2,18,1,8,2,4,3,122,38,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,102,105, - 110,100,95,112,97,114,101,110,116,95,112,97,116,104,95,110, - 97,109,101,115,99,1,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,28,0, - 0,0,124,0,160,0,161,0,92,2,125,1,125,2,116,1, - 116,2,106,3,124,1,25,0,124,2,131,2,83,0,114,109, - 0,0,0,41,4,114,30,1,0,0,114,130,0,0,0,114, - 1,0,0,0,218,7,109,111,100,117,108,101,115,41,3,114, - 118,0,0,0,90,18,112,97,114,101,110,116,95,109,111,100, - 117,108,101,95,110,97,109,101,90,14,112,97,116,104,95,97, - 116,116,114,95,110,97,109,101,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,25,1,0,0,139,4,0,0, - 115,4,0,0,0,0,1,12,1,122,31,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,103,101,116,95,112, - 97,114,101,110,116,95,112,97,116,104,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,4,0,0,0,67, - 0,0,0,115,80,0,0,0,116,0,124,0,160,1,161,0, - 131,1,125,1,124,1,124,0,106,2,107,3,114,74,124,0, - 160,3,124,0,106,4,124,1,161,2,125,2,124,2,100,0, - 117,1,114,68,124,2,106,5,100,0,117,0,114,68,124,2, - 106,6,114,68,124,2,106,6,124,0,95,7,124,1,124,0, - 95,2,124,0,106,7,83,0,114,109,0,0,0,41,8,114, - 111,0,0,0,114,25,1,0,0,114,26,1,0,0,114,27, - 1,0,0,114,23,1,0,0,114,140,0,0,0,114,178,0, - 0,0,114,24,1,0,0,41,3,114,118,0,0,0,90,11, - 112,97,114,101,110,116,95,112,97,116,104,114,187,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 12,95,114,101,99,97,108,99,117,108,97,116,101,143,4,0, - 0,115,16,0,0,0,0,2,12,1,10,1,14,3,18,1, - 6,1,8,1,6,1,122,27,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,114,101,99,97,108,99,117,108, - 97,116,101,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,12,0,0, - 0,116,0,124,0,160,1,161,0,131,1,83,0,114,109,0, - 0,0,41,2,114,6,1,0,0,114,32,1,0,0,114,246, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,8,95,95,105,116,101,114,95,95,156,4,0,0, - 115,2,0,0,0,0,1,122,23,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,95,105,116,101,114,95,95, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,2,0,0,0,67,0,0,0,115,12,0,0,0,124,0, - 160,0,161,0,124,1,25,0,83,0,114,109,0,0,0,169, - 1,114,32,1,0,0,41,2,114,118,0,0,0,218,5,105, - 110,100,101,120,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,218,11,95,95,103,101,116,105,116,101,109,95,95, - 159,4,0,0,115,2,0,0,0,0,1,122,26,95,78,97, - 109,101,115,112,97,99,101,80,97,116,104,46,95,95,103,101, - 116,105,116,101,109,95,95,99,3,0,0,0,0,0,0,0, + 8,0,0,0,114,213,0,0,0,80,4,0,0,115,2,0, + 0,0,0,2,122,28,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,103,101,116,95,99,111, + 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,1,83,0,41,2,122,53,82,101,116,117,114,110,32,78, + 111,110,101,32,97,115,32,101,120,116,101,110,115,105,111,110, + 32,109,111,100,117,108,101,115,32,104,97,118,101,32,110,111, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,5, + 0,0,0,114,219,0,0,0,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,229,0,0,0,84,4,0,0, + 115,2,0,0,0,0,2,122,30,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,6,0,0,0,124,0,106,0,83,0,114,250,0,0,0, + 114,48,0,0,0,114,219,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,179,0,0,0,88,4, + 0,0,115,2,0,0,0,0,3,122,32,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,103, + 101,116,95,102,105,108,101,110,97,109,101,78,41,14,114,125, + 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, + 0,0,114,209,0,0,0,114,243,0,0,0,114,247,0,0, + 0,114,212,0,0,0,114,217,0,0,0,114,182,0,0,0, + 114,213,0,0,0,114,229,0,0,0,114,136,0,0,0,114, + 179,0,0,0,114,5,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,252,0,0,0,41,4,0, + 0,115,22,0,0,0,8,2,4,6,8,4,8,4,8,3, + 8,8,8,6,8,6,8,4,8,4,2,1,114,252,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,64,0,0,0,115,104,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132, + 0,90,4,100,4,100,5,132,0,90,5,100,6,100,7,132, + 0,90,6,100,8,100,9,132,0,90,7,100,10,100,11,132, + 0,90,8,100,12,100,13,132,0,90,9,100,14,100,15,132, + 0,90,10,100,16,100,17,132,0,90,11,100,18,100,19,132, + 0,90,12,100,20,100,21,132,0,90,13,100,22,100,23,132, + 0,90,14,100,24,83,0,41,25,218,14,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,97,38,1,0,0,82,101, + 112,114,101,115,101,110,116,115,32,97,32,110,97,109,101,115, + 112,97,99,101,32,112,97,99,107,97,103,101,39,115,32,112, + 97,116,104,46,32,32,73,116,32,117,115,101,115,32,116,104, + 101,32,109,111,100,117,108,101,32,110,97,109,101,10,32,32, + 32,32,116,111,32,102,105,110,100,32,105,116,115,32,112,97, + 114,101,110,116,32,109,111,100,117,108,101,44,32,97,110,100, + 32,102,114,111,109,32,116,104,101,114,101,32,105,116,32,108, + 111,111,107,115,32,117,112,32,116,104,101,32,112,97,114,101, + 110,116,39,115,10,32,32,32,32,95,95,112,97,116,104,95, + 95,46,32,32,87,104,101,110,32,116,104,105,115,32,99,104, + 97,110,103,101,115,44,32,116,104,101,32,109,111,100,117,108, + 101,39,115,32,111,119,110,32,112,97,116,104,32,105,115,32, + 114,101,99,111,109,112,117,116,101,100,44,10,32,32,32,32, + 117,115,105,110,103,32,112,97,116,104,95,102,105,110,100,101, + 114,46,32,32,70,111,114,32,116,111,112,45,108,101,118,101, + 108,32,109,111,100,117,108,101,115,44,32,116,104,101,32,112, + 97,114,101,110,116,32,109,111,100,117,108,101,39,115,32,112, + 97,116,104,10,32,32,32,32,105,115,32,115,121,115,46,112, + 97,116,104,46,99,4,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,3,0,0,0,67,0,0,0,115,36,0, + 0,0,124,1,124,0,95,0,124,2,124,0,95,1,116,2, + 124,0,160,3,161,0,131,1,124,0,95,4,124,3,124,0, + 95,5,100,0,83,0,114,109,0,0,0,41,6,218,5,95, + 110,97,109,101,218,5,95,112,97,116,104,114,111,0,0,0, + 218,16,95,103,101,116,95,112,97,114,101,110,116,95,112,97, + 116,104,218,17,95,108,97,115,116,95,112,97,114,101,110,116, + 95,112,97,116,104,218,12,95,112,97,116,104,95,102,105,110, + 100,101,114,169,4,114,118,0,0,0,114,116,0,0,0,114, + 44,0,0,0,90,11,112,97,116,104,95,102,105,110,100,101, + 114,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 114,209,0,0,0,101,4,0,0,115,8,0,0,0,0,1, + 6,1,6,1,14,1,122,23,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,95,105,110,105,116,95,95,99, + 1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 3,0,0,0,67,0,0,0,115,38,0,0,0,124,0,106, + 0,160,1,100,1,161,1,92,3,125,1,125,2,125,3,124, + 2,100,2,107,2,114,30,100,3,83,0,124,1,100,4,102, + 2,83,0,41,5,122,62,82,101,116,117,114,110,115,32,97, + 32,116,117,112,108,101,32,111,102,32,40,112,97,114,101,110, + 116,45,109,111,100,117,108,101,45,110,97,109,101,44,32,112, + 97,114,101,110,116,45,112,97,116,104,45,97,116,116,114,45, + 110,97,109,101,41,114,71,0,0,0,114,40,0,0,0,41, + 2,114,1,0,0,0,114,44,0,0,0,90,8,95,95,112, + 97,116,104,95,95,41,2,114,14,1,0,0,114,41,0,0, + 0,41,4,114,118,0,0,0,114,4,1,0,0,218,3,100, + 111,116,90,2,109,101,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,23,95,102,105,110,100,95,112,97,114, + 101,110,116,95,112,97,116,104,95,110,97,109,101,115,107,4, + 0,0,115,8,0,0,0,0,2,18,1,8,2,4,3,122, + 38,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,102,105,110,100,95,112,97,114,101,110,116,95,112,97,116, + 104,95,110,97,109,101,115,99,1,0,0,0,0,0,0,0, 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, - 115,14,0,0,0,124,2,124,0,106,0,124,1,60,0,100, - 0,83,0,114,109,0,0,0,41,1,114,24,1,0,0,41, - 3,114,118,0,0,0,114,35,1,0,0,114,44,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 11,95,95,115,101,116,105,116,101,109,95,95,162,4,0,0, - 115,2,0,0,0,0,1,122,26,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,95,115,101,116,105,116,101, - 109,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,12,0,0, - 0,116,0,124,0,160,1,161,0,131,1,83,0,114,109,0, - 0,0,41,2,114,23,0,0,0,114,32,1,0,0,114,246, + 115,28,0,0,0,124,0,160,0,161,0,92,2,125,1,125, + 2,116,1,116,2,106,3,124,1,25,0,124,2,131,2,83, + 0,114,109,0,0,0,41,4,114,21,1,0,0,114,130,0, + 0,0,114,1,0,0,0,218,7,109,111,100,117,108,101,115, + 41,3,114,118,0,0,0,90,18,112,97,114,101,110,116,95, + 109,111,100,117,108,101,95,110,97,109,101,90,14,112,97,116, + 104,95,97,116,116,114,95,110,97,109,101,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,16,1,0,0,117, + 4,0,0,115,4,0,0,0,0,1,12,1,122,31,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,103,101, + 116,95,112,97,114,101,110,116,95,112,97,116,104,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,80,0,0,0,116,0,124,0,160, + 1,161,0,131,1,125,1,124,1,124,0,106,2,107,3,114, + 74,124,0,160,3,124,0,106,4,124,1,161,2,125,2,124, + 2,100,0,117,1,114,68,124,2,106,5,100,0,117,0,114, + 68,124,2,106,6,114,68,124,2,106,6,124,0,95,7,124, + 1,124,0,95,2,124,0,106,7,83,0,114,109,0,0,0, + 41,8,114,111,0,0,0,114,16,1,0,0,114,17,1,0, + 0,114,18,1,0,0,114,14,1,0,0,114,140,0,0,0, + 114,178,0,0,0,114,15,1,0,0,41,3,114,118,0,0, + 0,90,11,112,97,114,101,110,116,95,112,97,116,104,114,187, 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,7,95,95,108,101,110,95,95,165,4,0,0,115, - 2,0,0,0,0,1,122,22,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,95,108,101,110,95,95,99,1, - 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3, - 0,0,0,67,0,0,0,115,12,0,0,0,100,1,160,0, - 124,0,106,1,161,1,83,0,41,2,78,122,20,95,78,97, - 109,101,115,112,97,99,101,80,97,116,104,40,123,33,114,125, - 41,41,2,114,62,0,0,0,114,24,1,0,0,114,246,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,8,95,95,114,101,112,114,95,95,168,4,0,0,115, - 2,0,0,0,0,1,122,23,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,95,95,114,101,112,114,95,95,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,12,0,0,0,124,1,124, - 0,160,0,161,0,118,0,83,0,114,109,0,0,0,114,34, - 1,0,0,169,2,114,118,0,0,0,218,4,105,116,101,109, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, - 12,95,95,99,111,110,116,97,105,110,115,95,95,171,4,0, - 0,115,2,0,0,0,0,1,122,27,95,78,97,109,101,115, - 112,97,99,101,80,97,116,104,46,95,95,99,111,110,116,97, - 105,110,115,95,95,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,16, - 0,0,0,124,0,106,0,160,1,124,1,161,1,1,0,100, - 0,83,0,114,109,0,0,0,41,2,114,24,1,0,0,114, - 186,0,0,0,114,40,1,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,186,0,0,0,174,4,0, - 0,115,2,0,0,0,0,1,122,21,95,78,97,109,101,115, - 112,97,99,101,80,97,116,104,46,97,112,112,101,110,100,78, - 41,15,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,127,0,0,0,114,209,0,0,0,114,30,1,0,0, - 114,25,1,0,0,114,32,1,0,0,114,33,1,0,0,114, - 36,1,0,0,114,37,1,0,0,114,38,1,0,0,114,39, - 1,0,0,114,42,1,0,0,114,186,0,0,0,114,5,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,22,1,0,0,116,4,0,0,115,24,0,0,0,8, - 1,4,6,8,6,8,10,8,4,8,13,8,3,8,3,8, - 3,8,3,8,3,8,3,114,22,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,64,0,0,0,115,80,0,0,0,101,0,90,1,100,0, - 90,2,100,1,100,2,132,0,90,3,101,4,100,3,100,4, - 132,0,131,1,90,5,100,5,100,6,132,0,90,6,100,7, - 100,8,132,0,90,7,100,9,100,10,132,0,90,8,100,11, - 100,12,132,0,90,9,100,13,100,14,132,0,90,10,100,15, - 100,16,132,0,90,11,100,17,83,0,41,18,218,16,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,99,4, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4, - 0,0,0,67,0,0,0,115,18,0,0,0,116,0,124,1, - 124,2,124,3,131,3,124,0,95,1,100,0,83,0,114,109, - 0,0,0,41,2,114,22,1,0,0,114,24,1,0,0,114, - 28,1,0,0,114,5,0,0,0,114,5,0,0,0,114,8, - 0,0,0,114,209,0,0,0,180,4,0,0,115,2,0,0, - 0,0,1,122,25,95,78,97,109,101,115,112,97,99,101,76, - 111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, - 0,0,0,67,0,0,0,115,12,0,0,0,100,1,160,0, - 124,1,106,1,161,1,83,0,41,2,122,115,82,101,116,117, - 114,110,32,114,101,112,114,32,102,111,114,32,116,104,101,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,101,32,109,101,116,104,111,100,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,46,32,32,84,104,101,32, - 105,109,112,111,114,116,32,109,97,99,104,105,110,101,114,121, - 32,100,111,101,115,32,116,104,101,32,106,111,98,32,105,116, - 115,101,108,102,46,10,10,32,32,32,32,32,32,32,32,122, - 25,60,109,111,100,117,108,101,32,123,33,114,125,32,40,110, - 97,109,101,115,112,97,99,101,41,62,41,2,114,62,0,0, - 0,114,125,0,0,0,41,2,114,193,0,0,0,114,216,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,218,11,109,111,100,117,108,101,95,114,101,112,114,183,4, - 0,0,115,2,0,0,0,0,7,122,28,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,109,111,100,117, - 108,101,95,114,101,112,114,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,83,0,41,2,78,84,114,5,0, - 0,0,114,219,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,182,0,0,0,192,4,0,0,115, - 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, - 97,103,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,83,0,41,2,78,114,40,0,0,0,114,5,0, - 0,0,114,219,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,229,0,0,0,195,4,0,0,115, - 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,6,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,100,1,100,2,100,3,100,4,100,5,141,4,83, - 0,41,6,78,114,40,0,0,0,122,8,60,115,116,114,105, - 110,103,62,114,215,0,0,0,84,41,1,114,231,0,0,0, - 41,1,114,232,0,0,0,114,219,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,213,0,0,0, - 198,4,0,0,115,2,0,0,0,0,1,122,25,95,78,97, - 109,101,115,112,97,99,101,76,111,97,100,101,114,46,103,101, - 116,95,99,111,100,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,114,210,0,0,0,114,5,0, - 0,0,114,211,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,212,0,0,0,201,4,0,0,115, - 2,0,0,0,0,1,122,30,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,99,114,101,97,116,101,95, - 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,0,83,0,114,109,0,0,0,114,5,0, - 0,0,114,253,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,217,0,0,0,204,4,0,0,115, - 2,0,0,0,0,1,122,28,95,78,97,109,101,115,112,97, - 99,101,76,111,97,100,101,114,46,101,120,101,99,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,67,0,0,0,115,26,0, - 0,0,116,0,160,1,100,1,124,0,106,2,161,2,1,0, - 116,0,160,3,124,0,124,1,161,2,83,0,41,2,122,98, - 76,111,97,100,32,97,32,110,97,109,101,115,112,97,99,101, - 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,101,120,101,99,95,109,111,100,117,108,101,40,41,32, - 105,110,115,116,101,97,100,46,10,10,32,32,32,32,32,32, - 32,32,122,38,110,97,109,101,115,112,97,99,101,32,109,111, - 100,117,108,101,32,108,111,97,100,101,100,32,119,105,116,104, - 32,112,97,116,104,32,123,33,114,125,41,4,114,134,0,0, - 0,114,149,0,0,0,114,24,1,0,0,114,218,0,0,0, - 114,219,0,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,220,0,0,0,207,4,0,0,115,8,0, - 0,0,0,7,6,1,4,255,4,2,122,28,95,78,97,109, - 101,115,112,97,99,101,76,111,97,100,101,114,46,108,111,97, - 100,95,109,111,100,117,108,101,78,41,12,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,209,0,0,0,114, - 207,0,0,0,114,44,1,0,0,114,182,0,0,0,114,229, - 0,0,0,114,213,0,0,0,114,212,0,0,0,114,217,0, - 0,0,114,220,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,43,1,0,0, - 179,4,0,0,115,18,0,0,0,8,1,8,3,2,1,10, - 8,8,3,8,3,8,3,8,3,8,3,114,43,1,0,0, + 0,0,218,12,95,114,101,99,97,108,99,117,108,97,116,101, + 121,4,0,0,115,16,0,0,0,0,2,12,1,10,1,14, + 3,18,1,6,1,8,1,6,1,122,27,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,114,101,99,97,108, + 99,117,108,97,116,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 12,0,0,0,116,0,124,0,160,1,161,0,131,1,83,0, + 114,109,0,0,0,41,2,218,4,105,116,101,114,114,23,1, + 0,0,114,246,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,218,8,95,95,105,116,101,114,95,95, + 134,4,0,0,115,2,0,0,0,0,1,122,23,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,46,95,95,105,116, + 101,114,95,95,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,2,0,0,0,67,0,0,0,115,12,0, + 0,0,124,0,160,0,161,0,124,1,25,0,83,0,114,109, + 0,0,0,169,1,114,23,1,0,0,41,2,114,118,0,0, + 0,218,5,105,110,100,101,120,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,218,11,95,95,103,101,116,105,116, + 101,109,95,95,137,4,0,0,115,2,0,0,0,0,1,122, + 26,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,103,101,116,105,116,101,109,95,95,99,3,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 67,0,0,0,115,14,0,0,0,124,2,124,0,106,0,124, + 1,60,0,100,0,83,0,114,109,0,0,0,41,1,114,15, + 1,0,0,41,3,114,118,0,0,0,114,27,1,0,0,114, + 44,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,11,95,95,115,101,116,105,116,101,109,95,95, + 140,4,0,0,115,2,0,0,0,0,1,122,26,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,46,95,95,115,101, + 116,105,116,101,109,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,12,0,0,0,116,0,124,0,160,1,161,0,131,1,83, + 0,114,109,0,0,0,41,2,114,23,0,0,0,114,23,1, + 0,0,114,246,0,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,218,7,95,95,108,101,110,95,95,143, + 4,0,0,115,2,0,0,0,0,1,122,22,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,108,101,110, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, + 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122, + 20,95,78,97,109,101,115,112,97,99,101,80,97,116,104,40, + 123,33,114,125,41,41,2,114,62,0,0,0,114,15,1,0, + 0,114,246,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,8,95,95,114,101,112,114,95,95,146, + 4,0,0,115,2,0,0,0,0,1,122,23,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,114,101,112, + 114,95,95,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,67,0,0,0,115,12,0,0, + 0,124,1,124,0,160,0,161,0,118,0,83,0,114,109,0, + 0,0,114,26,1,0,0,169,2,114,118,0,0,0,218,4, + 105,116,101,109,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,218,12,95,95,99,111,110,116,97,105,110,115,95, + 95,149,4,0,0,115,2,0,0,0,0,1,122,27,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,99, + 111,110,116,97,105,110,115,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0, + 0,0,115,16,0,0,0,124,0,106,0,160,1,124,1,161, + 1,1,0,100,0,83,0,114,109,0,0,0,41,2,114,15, + 1,0,0,114,186,0,0,0,114,32,1,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,114,186,0,0, + 0,152,4,0,0,115,2,0,0,0,0,1,122,21,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,97,112,112, + 101,110,100,78,41,15,114,125,0,0,0,114,124,0,0,0, + 114,126,0,0,0,114,127,0,0,0,114,209,0,0,0,114, + 21,1,0,0,114,16,1,0,0,114,23,1,0,0,114,25, + 1,0,0,114,28,1,0,0,114,29,1,0,0,114,30,1, + 0,0,114,31,1,0,0,114,34,1,0,0,114,186,0,0, + 0,114,5,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,13,1,0,0,94,4,0,0,115,24, + 0,0,0,8,1,4,6,8,6,8,10,8,4,8,13,8, + 3,8,3,8,3,8,3,8,3,8,3,114,13,1,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,118,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,101,4,100,2,100,3, - 132,0,131,1,90,5,101,4,100,4,100,5,132,0,131,1, - 90,6,101,4,100,6,100,7,132,0,131,1,90,7,101,4, - 100,8,100,9,132,0,131,1,90,8,101,4,100,19,100,11, - 100,12,132,1,131,1,90,9,101,4,100,20,100,13,100,14, - 132,1,131,1,90,10,101,4,100,21,100,15,100,16,132,1, - 131,1,90,11,101,4,100,17,100,18,132,0,131,1,90,12, - 100,10,83,0,41,22,218,10,80,97,116,104,70,105,110,100, - 101,114,122,62,77,101,116,97,32,112,97,116,104,32,102,105, - 110,100,101,114,32,102,111,114,32,115,121,115,46,112,97,116, - 104,32,97,110,100,32,112,97,99,107,97,103,101,32,95,95, - 112,97,116,104,95,95,32,97,116,116,114,105,98,117,116,101, - 115,46,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,4,0,0,0,67,0,0,0,115,64,0,0,0, - 116,0,116,1,106,2,160,3,161,0,131,1,68,0,93,44, - 92,2,125,1,125,2,124,2,100,1,117,0,114,40,116,1, - 106,2,124,1,61,0,113,14,116,4,124,2,100,2,131,2, - 114,14,124,2,160,5,161,0,1,0,113,14,100,1,83,0, - 41,3,122,125,67,97,108,108,32,116,104,101,32,105,110,118, - 97,108,105,100,97,116,101,95,99,97,99,104,101,115,40,41, - 32,109,101,116,104,111,100,32,111,110,32,97,108,108,32,112, - 97,116,104,32,101,110,116,114,121,32,102,105,110,100,101,114, - 115,10,32,32,32,32,32,32,32,32,115,116,111,114,101,100, - 32,105,110,32,115,121,115,46,112,97,116,104,95,105,109,112, - 111,114,116,101,114,95,99,97,99,104,101,115,32,40,119,104, - 101,114,101,32,105,109,112,108,101,109,101,110,116,101,100,41, - 46,78,218,17,105,110,118,97,108,105,100,97,116,101,95,99, - 97,99,104,101,115,41,6,218,4,108,105,115,116,114,1,0, - 0,0,218,19,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,218,5,105,116,101,109,115,114,128, - 0,0,0,114,46,1,0,0,41,3,114,193,0,0,0,114, - 116,0,0,0,218,6,102,105,110,100,101,114,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,114,46,1,0,0, - 225,4,0,0,115,10,0,0,0,0,4,22,1,8,1,10, - 1,10,1,122,28,80,97,116,104,70,105,110,100,101,114,46, - 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, - 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,9,0,0,0,67,0,0,0,115,82,0,0,0,116, - 0,106,1,100,1,117,1,114,28,116,0,106,1,115,28,116, - 2,160,3,100,2,116,4,161,2,1,0,116,0,106,1,68, - 0,93,42,125,2,122,14,124,2,124,1,131,1,87,0,2, - 0,1,0,83,0,4,0,116,5,121,74,1,0,1,0,1, - 0,89,0,113,34,89,0,113,34,48,0,113,34,100,1,83, - 0,41,3,122,46,83,101,97,114,99,104,32,115,121,115,46, - 112,97,116,104,95,104,111,111,107,115,32,102,111,114,32,97, - 32,102,105,110,100,101,114,32,102,111,114,32,39,112,97,116, - 104,39,46,78,122,23,115,121,115,46,112,97,116,104,95,104, - 111,111,107,115,32,105,115,32,101,109,112,116,121,41,6,114, - 1,0,0,0,218,10,112,97,116,104,95,104,111,111,107,115, - 114,75,0,0,0,114,76,0,0,0,114,138,0,0,0,114, - 117,0,0,0,41,3,114,193,0,0,0,114,44,0,0,0, - 90,4,104,111,111,107,114,5,0,0,0,114,5,0,0,0, - 114,8,0,0,0,218,11,95,112,97,116,104,95,104,111,111, - 107,115,235,4,0,0,115,16,0,0,0,0,3,16,1,12, - 1,10,1,2,1,14,1,12,1,12,2,122,22,80,97,116, - 104,70,105,110,100,101,114,46,95,112,97,116,104,95,104,111, - 111,107,115,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,8,0,0,0,67,0,0,0,115,100,0,0, - 0,124,1,100,1,107,2,114,42,122,12,116,0,160,1,161, - 0,125,1,87,0,110,20,4,0,116,2,121,40,1,0,1, - 0,1,0,89,0,100,2,83,0,48,0,122,14,116,3,106, - 4,124,1,25,0,125,2,87,0,110,38,4,0,116,5,121, - 94,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, - 2,124,2,116,3,106,4,124,1,60,0,89,0,110,2,48, - 0,124,2,83,0,41,3,122,210,71,101,116,32,116,104,101, - 32,102,105,110,100,101,114,32,102,111,114,32,116,104,101,32, - 112,97,116,104,32,101,110,116,114,121,32,102,114,111,109,32, + 0,3,0,0,0,64,0,0,0,115,80,0,0,0,101,0, + 90,1,100,0,90,2,100,1,100,2,132,0,90,3,101,4, + 100,3,100,4,132,0,131,1,90,5,100,5,100,6,132,0, + 90,6,100,7,100,8,132,0,90,7,100,9,100,10,132,0, + 90,8,100,11,100,12,132,0,90,9,100,13,100,14,132,0, + 90,10,100,15,100,16,132,0,90,11,100,17,83,0,41,18, + 218,16,95,78,97,109,101,115,112,97,99,101,76,111,97,100, + 101,114,99,4,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,4,0,0,0,67,0,0,0,115,18,0,0,0, + 116,0,124,1,124,2,124,3,131,3,124,0,95,1,100,0, + 83,0,114,109,0,0,0,41,2,114,13,1,0,0,114,15, + 1,0,0,114,19,1,0,0,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,209,0,0,0,158,4,0,0, + 115,2,0,0,0,0,1,122,25,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,46,95,95,105,110,105,116, + 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, + 100,1,160,0,124,1,106,1,161,1,83,0,41,2,122,115, + 82,101,116,117,114,110,32,114,101,112,114,32,102,111,114,32, + 116,104,101,32,109,111,100,117,108,101,46,10,10,32,32,32, + 32,32,32,32,32,84,104,101,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, + 84,104,101,32,105,109,112,111,114,116,32,109,97,99,104,105, + 110,101,114,121,32,100,111,101,115,32,116,104,101,32,106,111, + 98,32,105,116,115,101,108,102,46,10,10,32,32,32,32,32, + 32,32,32,122,25,60,109,111,100,117,108,101,32,123,33,114, + 125,32,40,110,97,109,101,115,112,97,99,101,41,62,41,2, + 114,62,0,0,0,114,125,0,0,0,41,2,114,193,0,0, + 0,114,216,0,0,0,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,218,11,109,111,100,117,108,101,95,114,101, + 112,114,161,4,0,0,115,2,0,0,0,0,7,122,28,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 109,111,100,117,108,101,95,114,101,112,114,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,78, + 84,114,5,0,0,0,114,219,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,182,0,0,0,170, + 4,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,105,115,95, + 112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,83,0,41,2,78,114,40,0,0, + 0,114,5,0,0,0,114,219,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,229,0,0,0,173, + 4,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,103,101,116, + 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,6,0,0,0,67,0,0,0, + 115,16,0,0,0,116,0,100,1,100,2,100,3,100,4,100, + 5,141,4,83,0,41,6,78,114,40,0,0,0,122,8,60, + 115,116,114,105,110,103,62,114,215,0,0,0,84,41,1,114, + 231,0,0,0,41,1,114,232,0,0,0,114,219,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, + 213,0,0,0,176,4,0,0,115,2,0,0,0,0,1,122, + 25,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,114,210,0,0, + 0,114,5,0,0,0,114,211,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,212,0,0,0,179, + 4,0,0,115,2,0,0,0,0,1,122,30,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,99,114,101, + 97,116,101,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,0,83,0,114,109,0,0, + 0,114,5,0,0,0,114,6,1,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,217,0,0,0,182, + 4,0,0,115,2,0,0,0,0,1,122,28,95,78,97,109, + 101,115,112,97,99,101,76,111,97,100,101,114,46,101,120,101, + 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, + 0,115,26,0,0,0,116,0,160,1,100,1,124,0,106,2, + 161,2,1,0,116,0,160,3,124,0,124,1,161,2,83,0, + 41,2,122,98,76,111,97,100,32,97,32,110,97,109,101,115, + 112,97,99,101,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,32,32,32,32,84,104,105,115,32,109,101,116,104,111, + 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, + 32,32,85,115,101,32,101,120,101,99,95,109,111,100,117,108, + 101,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, + 32,32,32,32,32,32,122,38,110,97,109,101,115,112,97,99, + 101,32,109,111,100,117,108,101,32,108,111,97,100,101,100,32, + 119,105,116,104,32,112,97,116,104,32,123,33,114,125,41,4, + 114,134,0,0,0,114,149,0,0,0,114,15,1,0,0,114, + 218,0,0,0,114,219,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,220,0,0,0,185,4,0, + 0,115,8,0,0,0,0,7,6,1,4,255,4,2,122,28, + 95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,114, + 46,108,111,97,100,95,109,111,100,117,108,101,78,41,12,114, + 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,209, + 0,0,0,114,207,0,0,0,114,36,1,0,0,114,182,0, + 0,0,114,229,0,0,0,114,213,0,0,0,114,212,0,0, + 0,114,217,0,0,0,114,220,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, + 35,1,0,0,157,4,0,0,115,18,0,0,0,8,1,8, + 3,2,1,10,8,8,3,8,3,8,3,8,3,8,3,114, + 35,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,118,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,101,4, + 100,2,100,3,132,0,131,1,90,5,101,4,100,4,100,5, + 132,0,131,1,90,6,101,4,100,6,100,7,132,0,131,1, + 90,7,101,4,100,8,100,9,132,0,131,1,90,8,101,4, + 100,19,100,11,100,12,132,1,131,1,90,9,101,4,100,20, + 100,13,100,14,132,1,131,1,90,10,101,4,100,21,100,15, + 100,16,132,1,131,1,90,11,101,4,100,17,100,18,132,0, + 131,1,90,12,100,10,83,0,41,22,218,10,80,97,116,104, + 70,105,110,100,101,114,122,62,77,101,116,97,32,112,97,116, + 104,32,102,105,110,100,101,114,32,102,111,114,32,115,121,115, + 46,112,97,116,104,32,97,110,100,32,112,97,99,107,97,103, + 101,32,95,95,112,97,116,104,95,95,32,97,116,116,114,105, + 98,117,116,101,115,46,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 64,0,0,0,116,0,116,1,106,2,160,3,161,0,131,1, + 68,0,93,44,92,2,125,1,125,2,124,2,100,1,117,0, + 114,40,116,1,106,2,124,1,61,0,113,14,116,4,124,2, + 100,2,131,2,114,14,124,2,160,5,161,0,1,0,113,14, + 100,1,83,0,41,3,122,125,67,97,108,108,32,116,104,101, + 32,105,110,118,97,108,105,100,97,116,101,95,99,97,99,104, + 101,115,40,41,32,109,101,116,104,111,100,32,111,110,32,97, + 108,108,32,112,97,116,104,32,101,110,116,114,121,32,102,105, + 110,100,101,114,115,10,32,32,32,32,32,32,32,32,115,116, + 111,114,101,100,32,105,110,32,115,121,115,46,112,97,116,104, + 95,105,109,112,111,114,116,101,114,95,99,97,99,104,101,115, + 32,40,119,104,101,114,101,32,105,109,112,108,101,109,101,110, + 116,101,100,41,46,78,218,17,105,110,118,97,108,105,100,97, + 116,101,95,99,97,99,104,101,115,41,6,218,4,108,105,115, + 116,114,1,0,0,0,218,19,112,97,116,104,95,105,109,112, + 111,114,116,101,114,95,99,97,99,104,101,218,5,105,116,101, + 109,115,114,128,0,0,0,114,38,1,0,0,41,3,114,193, + 0,0,0,114,116,0,0,0,218,6,102,105,110,100,101,114, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, + 38,1,0,0,203,4,0,0,115,10,0,0,0,0,4,22, + 1,8,1,10,1,10,1,122,28,80,97,116,104,70,105,110, + 100,101,114,46,105,110,118,97,108,105,100,97,116,101,95,99, + 97,99,104,101,115,99,2,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,9,0,0,0,67,0,0,0,115,82, + 0,0,0,116,0,106,1,100,1,117,1,114,28,116,0,106, + 1,115,28,116,2,160,3,100,2,116,4,161,2,1,0,116, + 0,106,1,68,0,93,42,125,2,122,14,124,2,124,1,131, + 1,87,0,2,0,1,0,83,0,4,0,116,5,121,74,1, + 0,1,0,1,0,89,0,113,34,89,0,113,34,48,0,113, + 34,100,1,83,0,41,3,122,46,83,101,97,114,99,104,32, + 115,121,115,46,112,97,116,104,95,104,111,111,107,115,32,102, + 111,114,32,97,32,102,105,110,100,101,114,32,102,111,114,32, + 39,112,97,116,104,39,46,78,122,23,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,105,115,32,101,109,112,116, + 121,41,6,114,1,0,0,0,218,10,112,97,116,104,95,104, + 111,111,107,115,114,75,0,0,0,114,76,0,0,0,114,138, + 0,0,0,114,117,0,0,0,41,3,114,193,0,0,0,114, + 44,0,0,0,90,4,104,111,111,107,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,218,11,95,112,97,116,104, + 95,104,111,111,107,115,213,4,0,0,115,16,0,0,0,0, + 3,16,1,12,1,10,1,2,1,14,1,12,1,12,2,122, + 22,80,97,116,104,70,105,110,100,101,114,46,95,112,97,116, + 104,95,104,111,111,107,115,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,8,0,0,0,67,0,0,0, + 115,100,0,0,0,124,1,100,1,107,2,114,42,122,12,116, + 0,160,1,161,0,125,1,87,0,110,20,4,0,116,2,121, + 40,1,0,1,0,1,0,89,0,100,2,83,0,48,0,122, + 14,116,3,106,4,124,1,25,0,125,2,87,0,110,38,4, + 0,116,5,121,94,1,0,1,0,1,0,124,0,160,6,124, + 1,161,1,125,2,124,2,116,3,106,4,124,1,60,0,89, + 0,110,2,48,0,124,2,83,0,41,3,122,210,71,101,116, + 32,116,104,101,32,102,105,110,100,101,114,32,102,111,114,32, + 116,104,101,32,112,97,116,104,32,101,110,116,114,121,32,102, + 114,111,109,32,115,121,115,46,112,97,116,104,95,105,109,112, + 111,114,116,101,114,95,99,97,99,104,101,46,10,10,32,32, + 32,32,32,32,32,32,73,102,32,116,104,101,32,112,97,116, + 104,32,101,110,116,114,121,32,105,115,32,110,111,116,32,105, + 110,32,116,104,101,32,99,97,99,104,101,44,32,102,105,110, + 100,32,116,104,101,32,97,112,112,114,111,112,114,105,97,116, + 101,32,102,105,110,100,101,114,10,32,32,32,32,32,32,32, + 32,97,110,100,32,99,97,99,104,101,32,105,116,46,32,73, + 102,32,110,111,32,102,105,110,100,101,114,32,105,115,32,97, + 118,97,105,108,97,98,108,101,44,32,115,116,111,114,101,32, + 78,111,110,101,46,10,10,32,32,32,32,32,32,32,32,114, + 40,0,0,0,78,41,7,114,4,0,0,0,114,55,0,0, + 0,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, + 114,114,111,114,114,1,0,0,0,114,40,1,0,0,218,8, + 75,101,121,69,114,114,111,114,114,44,1,0,0,41,3,114, + 193,0,0,0,114,44,0,0,0,114,42,1,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,218,20,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,226,4,0,0,115,22,0,0,0,0,8,8,1, + 2,1,12,1,12,3,8,1,2,1,14,1,12,1,10,1, + 16,1,122,31,80,97,116,104,70,105,110,100,101,114,46,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,4,0,0,0,67,0,0,0,115,82,0,0, + 0,116,0,124,2,100,1,131,2,114,26,124,2,160,1,124, + 1,161,1,92,2,125,3,125,4,110,14,124,2,160,2,124, + 1,161,1,125,3,103,0,125,4,124,3,100,0,117,1,114, + 60,116,3,160,4,124,1,124,3,161,2,83,0,116,3,160, + 5,124,1,100,0,161,2,125,5,124,4,124,5,95,6,124, + 5,83,0,41,2,78,114,137,0,0,0,41,7,114,128,0, + 0,0,114,137,0,0,0,114,206,0,0,0,114,134,0,0, + 0,114,201,0,0,0,114,183,0,0,0,114,178,0,0,0, + 41,6,114,193,0,0,0,114,139,0,0,0,114,42,1,0, + 0,114,140,0,0,0,114,141,0,0,0,114,187,0,0,0, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, + 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, + 99,248,4,0,0,115,18,0,0,0,0,4,10,1,16,2, + 10,1,4,1,8,1,12,1,12,1,6,1,122,27,80,97, + 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, + 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, + 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, + 93,134,125,5,116,0,124,5,116,1,116,2,102,2,131,2, + 115,28,113,8,124,0,160,3,124,5,161,1,125,6,124,6, + 100,1,117,1,114,8,116,4,124,6,100,2,131,2,114,70, + 124,6,160,5,124,1,124,3,161,2,125,7,110,12,124,0, + 160,6,124,1,124,6,161,2,125,7,124,7,100,1,117,0, + 114,92,113,8,124,7,106,7,100,1,117,1,114,110,124,7, + 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, + 117,0,114,132,116,9,100,3,131,1,130,1,124,4,160,10, + 124,8,161,1,1,0,113,8,116,11,160,12,124,1,100,1, + 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, + 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, + 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, + 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, + 46,78,114,203,0,0,0,122,19,115,112,101,99,32,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,161, + 0,0,0,114,84,0,0,0,218,5,98,121,116,101,115,114, + 47,1,0,0,114,128,0,0,0,114,203,0,0,0,114,48, + 1,0,0,114,140,0,0,0,114,178,0,0,0,114,117,0, + 0,0,114,167,0,0,0,114,134,0,0,0,114,183,0,0, + 0,41,9,114,193,0,0,0,114,139,0,0,0,114,44,0, + 0,0,114,202,0,0,0,218,14,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,42, + 1,0,0,114,187,0,0,0,114,141,0,0,0,114,5,0, + 0,0,114,5,0,0,0,114,8,0,0,0,218,9,95,103, + 101,116,95,115,112,101,99,7,5,0,0,115,40,0,0,0, + 0,5,4,1,8,1,14,1,2,1,10,1,8,1,10,1, + 14,2,12,1,8,1,2,1,10,1,8,1,6,1,8,1, + 8,5,12,2,12,1,6,1,122,20,80,97,116,104,70,105, + 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5, + 0,0,0,67,0,0,0,115,100,0,0,0,124,2,100,1, + 117,0,114,14,116,0,106,1,125,2,124,0,160,2,124,1, + 124,2,124,3,161,3,125,4,124,4,100,1,117,0,114,40, + 100,1,83,0,124,4,106,3,100,1,117,0,114,92,124,4, + 106,4,125,5,124,5,114,86,100,1,124,4,95,5,116,6, + 124,1,124,5,124,0,106,2,131,3,124,4,95,4,124,4, + 83,0,100,1,83,0,110,4,124,4,83,0,100,1,83,0, + 41,2,122,141,84,114,121,32,116,111,32,102,105,110,100,32, + 97,32,115,112,101,99,32,102,111,114,32,39,102,117,108,108, + 110,97,109,101,39,32,111,110,32,115,121,115,46,112,97,116, + 104,32,111,114,32,39,112,97,116,104,39,46,10,10,32,32, + 32,32,32,32,32,32,84,104,101,32,115,101,97,114,99,104, + 32,105,115,32,98,97,115,101,100,32,111,110,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,115,32,97,110,100,32, 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,46,10,10,32,32,32,32,32,32, - 32,32,73,102,32,116,104,101,32,112,97,116,104,32,101,110, - 116,114,121,32,105,115,32,110,111,116,32,105,110,32,116,104, - 101,32,99,97,99,104,101,44,32,102,105,110,100,32,116,104, - 101,32,97,112,112,114,111,112,114,105,97,116,101,32,102,105, - 110,100,101,114,10,32,32,32,32,32,32,32,32,97,110,100, - 32,99,97,99,104,101,32,105,116,46,32,73,102,32,110,111, - 32,102,105,110,100,101,114,32,105,115,32,97,118,97,105,108, - 97,98,108,101,44,32,115,116,111,114,101,32,78,111,110,101, - 46,10,10,32,32,32,32,32,32,32,32,114,40,0,0,0, - 78,41,7,114,4,0,0,0,114,55,0,0,0,114,3,1, - 0,0,114,1,0,0,0,114,48,1,0,0,218,8,75,101, - 121,69,114,114,111,114,114,52,1,0,0,41,3,114,193,0, - 0,0,114,44,0,0,0,114,50,1,0,0,114,5,0,0, - 0,114,5,0,0,0,114,8,0,0,0,218,20,95,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,248,4,0,0,115,22,0,0,0,0,8,8,1,2,1, - 12,1,12,3,8,1,2,1,14,1,12,1,10,1,16,1, - 122,31,80,97,116,104,70,105,110,100,101,114,46,95,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,99,3,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,4,0,0,0,67,0,0,0,115,82,0,0,0,116, - 0,124,2,100,1,131,2,114,26,124,2,160,1,124,1,161, - 1,92,2,125,3,125,4,110,14,124,2,160,2,124,1,161, - 1,125,3,103,0,125,4,124,3,100,0,117,1,114,60,116, - 3,160,4,124,1,124,3,161,2,83,0,116,3,160,5,124, - 1,100,0,161,2,125,5,124,4,124,5,95,6,124,5,83, - 0,41,2,78,114,137,0,0,0,41,7,114,128,0,0,0, - 114,137,0,0,0,114,206,0,0,0,114,134,0,0,0,114, - 201,0,0,0,114,183,0,0,0,114,178,0,0,0,41,6, - 114,193,0,0,0,114,139,0,0,0,114,50,1,0,0,114, - 140,0,0,0,114,141,0,0,0,114,187,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,218,16,95, - 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,14, - 5,0,0,115,18,0,0,0,0,4,10,1,16,2,10,1, - 4,1,8,1,12,1,12,1,6,1,122,27,80,97,116,104, - 70,105,110,100,101,114,46,95,108,101,103,97,99,121,95,103, - 101,116,95,115,112,101,99,78,99,4,0,0,0,0,0,0, - 0,0,0,0,0,9,0,0,0,5,0,0,0,67,0,0, - 0,115,166,0,0,0,103,0,125,4,124,2,68,0,93,134, - 125,5,116,0,124,5,116,1,116,2,102,2,131,2,115,28, - 113,8,124,0,160,3,124,5,161,1,125,6,124,6,100,1, - 117,1,114,8,116,4,124,6,100,2,131,2,114,70,124,6, - 160,5,124,1,124,3,161,2,125,7,110,12,124,0,160,6, - 124,1,124,6,161,2,125,7,124,7,100,1,117,0,114,92, - 113,8,124,7,106,7,100,1,117,1,114,110,124,7,2,0, - 1,0,83,0,124,7,106,8,125,8,124,8,100,1,117,0, - 114,132,116,9,100,3,131,1,130,1,124,4,160,10,124,8, - 161,1,1,0,113,8,116,11,160,12,124,1,100,1,161,2, - 125,7,124,4,124,7,95,8,124,7,83,0,41,4,122,63, - 70,105,110,100,32,116,104,101,32,108,111,97,100,101,114,32, - 111,114,32,110,97,109,101,115,112,97,99,101,95,112,97,116, - 104,32,102,111,114,32,116,104,105,115,32,109,111,100,117,108, - 101,47,112,97,99,107,97,103,101,32,110,97,109,101,46,78, - 114,203,0,0,0,122,19,115,112,101,99,32,109,105,115,115, - 105,110,103,32,108,111,97,100,101,114,41,13,114,161,0,0, - 0,114,84,0,0,0,218,5,98,121,116,101,115,114,54,1, - 0,0,114,128,0,0,0,114,203,0,0,0,114,55,1,0, - 0,114,140,0,0,0,114,178,0,0,0,114,117,0,0,0, - 114,167,0,0,0,114,134,0,0,0,114,183,0,0,0,41, - 9,114,193,0,0,0,114,139,0,0,0,114,44,0,0,0, - 114,202,0,0,0,218,14,110,97,109,101,115,112,97,99,101, - 95,112,97,116,104,90,5,101,110,116,114,121,114,50,1,0, - 0,114,187,0,0,0,114,141,0,0,0,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,218,9,95,103,101,116, - 95,115,112,101,99,29,5,0,0,115,40,0,0,0,0,5, - 4,1,8,1,14,1,2,1,10,1,8,1,10,1,14,2, - 12,1,8,1,2,1,10,1,8,1,6,1,8,1,8,5, - 12,2,12,1,6,1,122,20,80,97,116,104,70,105,110,100, - 101,114,46,95,103,101,116,95,115,112,101,99,99,4,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0, - 0,67,0,0,0,115,100,0,0,0,124,2,100,1,117,0, - 114,14,116,0,106,1,125,2,124,0,160,2,124,1,124,2, - 124,3,161,3,125,4,124,4,100,1,117,0,114,40,100,1, - 83,0,124,4,106,3,100,1,117,0,114,92,124,4,106,4, - 125,5,124,5,114,86,100,1,124,4,95,5,116,6,124,1, - 124,5,124,0,106,2,131,3,124,4,95,4,124,4,83,0, - 100,1,83,0,110,4,124,4,83,0,100,1,83,0,41,2, - 122,141,84,114,121,32,116,111,32,102,105,110,100,32,97,32, - 115,112,101,99,32,102,111,114,32,39,102,117,108,108,110,97, - 109,101,39,32,111,110,32,115,121,115,46,112,97,116,104,32, - 111,114,32,39,112,97,116,104,39,46,10,10,32,32,32,32, - 32,32,32,32,84,104,101,32,115,101,97,114,99,104,32,105, - 115,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, - 97,116,104,95,104,111,111,107,115,32,97,110,100,32,115,121, + 114,95,99,97,99,104,101,46,10,32,32,32,32,32,32,32, + 32,78,41,7,114,1,0,0,0,114,44,0,0,0,114,51, + 1,0,0,114,140,0,0,0,114,178,0,0,0,114,181,0, + 0,0,114,13,1,0,0,41,6,114,193,0,0,0,114,139, + 0,0,0,114,44,0,0,0,114,202,0,0,0,114,187,0, + 0,0,114,50,1,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,114,203,0,0,0,39,5,0,0,115, + 26,0,0,0,0,6,8,1,6,1,14,1,8,1,4,1, + 10,1,6,1,4,3,6,1,16,1,4,2,6,2,122,20, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, + 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, + 100,1,117,0,114,24,100,1,83,0,124,3,106,1,83,0, + 41,2,122,170,102,105,110,100,32,116,104,101,32,109,111,100, + 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, + 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,46,10,32,32,32,32,32,32,32,32,78, - 41,7,114,1,0,0,0,114,44,0,0,0,114,58,1,0, - 0,114,140,0,0,0,114,178,0,0,0,114,181,0,0,0, - 114,22,1,0,0,41,6,114,193,0,0,0,114,139,0,0, - 0,114,44,0,0,0,114,202,0,0,0,114,187,0,0,0, - 114,57,1,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,203,0,0,0,61,5,0,0,115,26,0, - 0,0,0,6,8,1,6,1,14,1,8,1,4,1,10,1, - 6,1,4,3,6,1,16,1,4,2,6,2,122,20,80,97, - 116,104,70,105,110,100,101,114,46,102,105,110,100,95,115,112, - 101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,4,0,0,0,67,0,0,0,115,30,0,0,0, - 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,1, - 117,0,114,24,100,1,83,0,124,3,106,1,83,0,41,2, - 122,170,102,105,110,100,32,116,104,101,32,109,111,100,117,108, - 101,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, - 32,39,112,97,116,104,39,32,98,97,115,101,100,32,111,110, - 32,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, - 97,110,100,10,32,32,32,32,32,32,32,32,115,121,115,46, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,32,32,85,115,101,32,102,105, - 110,100,95,115,112,101,99,40,41,32,105,110,115,116,101,97, - 100,46,10,10,32,32,32,32,32,32,32,32,78,114,204,0, - 0,0,114,205,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,206,0,0,0,85,5,0,0,115, - 8,0,0,0,0,8,12,1,8,1,4,1,122,22,80,97, - 116,104,70,105,110,100,101,114,46,102,105,110,100,95,109,111, - 100,117,108,101,99,1,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,4,0,0,0,79,0,0,0,115,28,0, - 0,0,100,1,100,2,108,0,109,1,125,3,1,0,124,3, - 106,2,124,1,105,0,124,2,164,1,142,1,83,0,41,3, - 97,32,1,0,0,10,32,32,32,32,32,32,32,32,70,105, - 110,100,32,100,105,115,116,114,105,98,117,116,105,111,110,115, - 46,10,10,32,32,32,32,32,32,32,32,82,101,116,117,114, - 110,32,97,110,32,105,116,101,114,97,98,108,101,32,111,102, - 32,97,108,108,32,68,105,115,116,114,105,98,117,116,105,111, - 110,32,105,110,115,116,97,110,99,101,115,32,99,97,112,97, - 98,108,101,32,111,102,10,32,32,32,32,32,32,32,32,108, - 111,97,100,105,110,103,32,116,104,101,32,109,101,116,97,100, - 97,116,97,32,102,111,114,32,112,97,99,107,97,103,101,115, - 32,109,97,116,99,104,105,110,103,32,96,96,99,111,110,116, - 101,120,116,46,110,97,109,101,96,96,10,32,32,32,32,32, - 32,32,32,40,111,114,32,97,108,108,32,110,97,109,101,115, - 32,105,102,32,96,96,78,111,110,101,96,96,32,105,110,100, - 105,99,97,116,101,100,41,32,97,108,111,110,103,32,116,104, - 101,32,112,97,116,104,115,32,105,110,32,116,104,101,32,108, - 105,115,116,10,32,32,32,32,32,32,32,32,111,102,32,100, - 105,114,101,99,116,111,114,105,101,115,32,96,96,99,111,110, - 116,101,120,116,46,112,97,116,104,96,96,46,10,32,32,32, - 32,32,32,32,32,114,73,0,0,0,41,1,218,18,77,101, - 116,97,100,97,116,97,80,97,116,104,70,105,110,100,101,114, - 41,3,90,18,105,109,112,111,114,116,108,105,98,46,109,101, - 116,97,100,97,116,97,114,59,1,0,0,218,18,102,105,110, - 100,95,100,105,115,116,114,105,98,117,116,105,111,110,115,41, - 4,114,193,0,0,0,114,119,0,0,0,114,120,0,0,0, - 114,59,1,0,0,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,114,60,1,0,0,98,5,0,0,115,4,0, - 0,0,0,10,12,1,122,29,80,97,116,104,70,105,110,100, - 101,114,46,102,105,110,100,95,100,105,115,116,114,105,98,117, - 116,105,111,110,115,41,1,78,41,2,78,78,41,1,78,41, - 13,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,207,0,0,0,114,46,1,0,0,114, - 52,1,0,0,114,54,1,0,0,114,55,1,0,0,114,58, - 1,0,0,114,203,0,0,0,114,206,0,0,0,114,60,1, - 0,0,114,5,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,45,1,0,0,221,4,0,0,115, - 34,0,0,0,8,2,4,2,2,1,10,9,2,1,10,12, - 2,1,10,21,2,1,10,14,2,1,12,31,2,1,12,23, - 2,1,12,12,2,1,114,45,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 64,0,0,0,115,90,0,0,0,101,0,90,1,100,0,90, - 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, - 5,132,0,90,5,101,6,90,7,100,6,100,7,132,0,90, - 8,100,8,100,9,132,0,90,9,100,19,100,11,100,12,132, - 1,90,10,100,13,100,14,132,0,90,11,101,12,100,15,100, - 16,132,0,131,1,90,13,100,17,100,18,132,0,90,14,100, - 10,83,0,41,20,218,10,70,105,108,101,70,105,110,100,101, - 114,122,172,70,105,108,101,45,98,97,115,101,100,32,102,105, - 110,100,101,114,46,10,10,32,32,32,32,73,110,116,101,114, - 97,99,116,105,111,110,115,32,119,105,116,104,32,116,104,101, - 32,102,105,108,101,32,115,121,115,116,101,109,32,97,114,101, - 32,99,97,99,104,101,100,32,102,111,114,32,112,101,114,102, - 111,114,109,97,110,99,101,44,32,98,101,105,110,103,10,32, - 32,32,32,114,101,102,114,101,115,104,101,100,32,119,104,101, - 110,32,116,104,101,32,100,105,114,101,99,116,111,114,121,32, - 116,104,101,32,102,105,110,100,101,114,32,105,115,32,104,97, - 110,100,108,105,110,103,32,104,97,115,32,98,101,101,110,32, - 109,111,100,105,102,105,101,100,46,10,10,32,32,32,32,99, - 2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 6,0,0,0,7,0,0,0,115,84,0,0,0,103,0,125, - 3,124,2,68,0,93,32,92,2,137,0,125,4,124,3,160, - 0,135,0,102,1,100,1,100,2,132,8,124,4,68,0,131, - 1,161,1,1,0,113,8,124,3,124,0,95,1,124,1,112, - 54,100,3,124,0,95,2,100,4,124,0,95,3,116,4,131, - 0,124,0,95,5,116,4,131,0,124,0,95,6,100,5,83, - 0,41,6,122,154,73,110,105,116,105,97,108,105,122,101,32, - 119,105,116,104,32,116,104,101,32,112,97,116,104,32,116,111, - 32,115,101,97,114,99,104,32,111,110,32,97,110,100,32,97, - 32,118,97,114,105,97,98,108,101,32,110,117,109,98,101,114, - 32,111,102,10,32,32,32,32,32,32,32,32,50,45,116,117, - 112,108,101,115,32,99,111,110,116,97,105,110,105,110,103,32, - 116,104,101,32,108,111,97,100,101,114,32,97,110,100,32,116, - 104,101,32,102,105,108,101,32,115,117,102,102,105,120,101,115, - 32,116,104,101,32,108,111,97,100,101,114,10,32,32,32,32, - 32,32,32,32,114,101,99,111,103,110,105,122,101,115,46,99, + 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,114, + 204,0,0,0,114,205,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,206,0,0,0,63,5,0, + 0,115,8,0,0,0,0,8,12,1,8,1,4,1,122,22, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,4,0,0,0,79,0,0,0,115, + 28,0,0,0,100,1,100,2,108,0,109,1,125,3,1,0, + 124,3,106,2,124,1,105,0,124,2,164,1,142,1,83,0, + 41,3,97,32,1,0,0,10,32,32,32,32,32,32,32,32, + 70,105,110,100,32,100,105,115,116,114,105,98,117,116,105,111, + 110,115,46,10,10,32,32,32,32,32,32,32,32,82,101,116, + 117,114,110,32,97,110,32,105,116,101,114,97,98,108,101,32, + 111,102,32,97,108,108,32,68,105,115,116,114,105,98,117,116, + 105,111,110,32,105,110,115,116,97,110,99,101,115,32,99,97, + 112,97,98,108,101,32,111,102,10,32,32,32,32,32,32,32, + 32,108,111,97,100,105,110,103,32,116,104,101,32,109,101,116, + 97,100,97,116,97,32,102,111,114,32,112,97,99,107,97,103, + 101,115,32,109,97,116,99,104,105,110,103,32,96,96,99,111, + 110,116,101,120,116,46,110,97,109,101,96,96,10,32,32,32, + 32,32,32,32,32,40,111,114,32,97,108,108,32,110,97,109, + 101,115,32,105,102,32,96,96,78,111,110,101,96,96,32,105, + 110,100,105,99,97,116,101,100,41,32,97,108,111,110,103,32, + 116,104,101,32,112,97,116,104,115,32,105,110,32,116,104,101, + 32,108,105,115,116,10,32,32,32,32,32,32,32,32,111,102, + 32,100,105,114,101,99,116,111,114,105,101,115,32,96,96,99, + 111,110,116,101,120,116,46,112,97,116,104,96,96,46,10,32, + 32,32,32,32,32,32,32,114,73,0,0,0,41,1,218,18, + 77,101,116,97,100,97,116,97,80,97,116,104,70,105,110,100, + 101,114,41,3,90,18,105,109,112,111,114,116,108,105,98,46, + 109,101,116,97,100,97,116,97,114,52,1,0,0,218,18,102, + 105,110,100,95,100,105,115,116,114,105,98,117,116,105,111,110, + 115,41,4,114,193,0,0,0,114,119,0,0,0,114,120,0, + 0,0,114,52,1,0,0,114,5,0,0,0,114,5,0,0, + 0,114,8,0,0,0,114,53,1,0,0,76,5,0,0,115, + 4,0,0,0,0,10,12,1,122,29,80,97,116,104,70,105, + 110,100,101,114,46,102,105,110,100,95,100,105,115,116,114,105, + 98,117,116,105,111,110,115,41,1,78,41,2,78,78,41,1, + 78,41,13,114,125,0,0,0,114,124,0,0,0,114,126,0, + 0,0,114,127,0,0,0,114,207,0,0,0,114,38,1,0, + 0,114,44,1,0,0,114,47,1,0,0,114,48,1,0,0, + 114,51,1,0,0,114,203,0,0,0,114,206,0,0,0,114, + 53,1,0,0,114,5,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,37,1,0,0,199,4,0, + 0,115,34,0,0,0,8,2,4,2,2,1,10,9,2,1, + 10,12,2,1,10,21,2,1,10,14,2,1,12,31,2,1, + 12,23,2,1,12,12,2,1,114,37,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,64,0,0,0,115,90,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, + 4,100,5,132,0,90,5,101,6,90,7,100,6,100,7,132, + 0,90,8,100,8,100,9,132,0,90,9,100,19,100,11,100, + 12,132,1,90,10,100,13,100,14,132,0,90,11,101,12,100, + 15,100,16,132,0,131,1,90,13,100,17,100,18,132,0,90, + 14,100,10,83,0,41,20,218,10,70,105,108,101,70,105,110, + 100,101,114,122,172,70,105,108,101,45,98,97,115,101,100,32, + 102,105,110,100,101,114,46,10,10,32,32,32,32,73,110,116, + 101,114,97,99,116,105,111,110,115,32,119,105,116,104,32,116, + 104,101,32,102,105,108,101,32,115,121,115,116,101,109,32,97, + 114,101,32,99,97,99,104,101,100,32,102,111,114,32,112,101, + 114,102,111,114,109,97,110,99,101,44,32,98,101,105,110,103, + 10,32,32,32,32,114,101,102,114,101,115,104,101,100,32,119, + 104,101,110,32,116,104,101,32,100,105,114,101,99,116,111,114, + 121,32,116,104,101,32,102,105,110,100,101,114,32,105,115,32, + 104,97,110,100,108,105,110,103,32,104,97,115,32,98,101,101, + 110,32,109,111,100,105,102,105,101,100,46,10,10,32,32,32, + 32,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,6,0,0,0,7,0,0,0,115,84,0,0,0,103, + 0,125,3,124,2,68,0,93,32,92,2,137,0,125,4,124, + 3,160,0,135,0,102,1,100,1,100,2,132,8,124,4,68, + 0,131,1,161,1,1,0,113,8,124,3,124,0,95,1,124, + 1,112,54,100,3,124,0,95,2,100,4,124,0,95,3,116, + 4,131,0,124,0,95,5,116,4,131,0,124,0,95,6,100, + 5,83,0,41,6,122,154,73,110,105,116,105,97,108,105,122, + 101,32,119,105,116,104,32,116,104,101,32,112,97,116,104,32, + 116,111,32,115,101,97,114,99,104,32,111,110,32,97,110,100, + 32,97,32,118,97,114,105,97,98,108,101,32,110,117,109,98, + 101,114,32,111,102,10,32,32,32,32,32,32,32,32,50,45, + 116,117,112,108,101,115,32,99,111,110,116,97,105,110,105,110, + 103,32,116,104,101,32,108,111,97,100,101,114,32,97,110,100, + 32,116,104,101,32,102,105,108,101,32,115,117,102,102,105,120, + 101,115,32,116,104,101,32,108,111,97,100,101,114,10,32,32, + 32,32,32,32,32,32,114,101,99,111,103,110,105,122,101,115, + 46,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,51,0,0,0,115,22,0,0,0,124, + 0,93,14,125,1,124,1,136,0,102,2,86,0,1,0,113, + 2,100,0,83,0,114,109,0,0,0,114,5,0,0,0,114, + 7,1,0,0,169,1,114,140,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,10,1,0,0,105,5,0,0,243,0, + 0,0,0,122,38,70,105,108,101,70,105,110,100,101,114,46, + 95,95,105,110,105,116,95,95,46,60,108,111,99,97,108,115, + 62,46,60,103,101,110,101,120,112,114,62,114,71,0,0,0, + 114,104,0,0,0,78,41,7,114,167,0,0,0,218,8,95, + 108,111,97,100,101,114,115,114,44,0,0,0,218,11,95,112, + 97,116,104,95,109,116,105,109,101,218,3,115,101,116,218,11, + 95,112,97,116,104,95,99,97,99,104,101,218,19,95,114,101, + 108,97,120,101,100,95,112,97,116,104,95,99,97,99,104,101, + 41,5,114,118,0,0,0,114,44,0,0,0,218,14,108,111, + 97,100,101,114,95,100,101,116,97,105,108,115,90,7,108,111, + 97,100,101,114,115,114,189,0,0,0,114,5,0,0,0,114, + 55,1,0,0,114,8,0,0,0,114,209,0,0,0,99,5, + 0,0,115,16,0,0,0,0,4,4,1,12,1,26,1,6, + 2,10,1,6,1,8,1,122,19,70,105,108,101,70,105,110, + 100,101,114,46,95,95,105,110,105,116,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0, + 0,67,0,0,0,115,10,0,0,0,100,1,124,0,95,0, + 100,2,83,0,41,3,122,31,73,110,118,97,108,105,100,97, + 116,101,32,116,104,101,32,100,105,114,101,99,116,111,114,121, + 32,109,116,105,109,101,46,114,104,0,0,0,78,41,1,114, + 58,1,0,0,114,246,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,38,1,0,0,113,5,0, + 0,115,2,0,0,0,0,2,122,28,70,105,108,101,70,105, + 110,100,101,114,46,105,110,118,97,108,105,100,97,116,101,95, + 99,97,99,104,101,115,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,67,0,0,0,115, + 42,0,0,0,124,0,160,0,124,1,161,1,125,2,124,2, + 100,1,117,0,114,26,100,1,103,0,102,2,83,0,124,2, + 106,1,124,2,106,2,112,38,103,0,102,2,83,0,41,2, + 122,197,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,44, + 32,111,114,32,116,104,101,32,110,97,109,101,115,112,97,99, + 101,10,32,32,32,32,32,32,32,32,112,97,99,107,97,103, + 101,32,112,111,114,116,105,111,110,115,46,32,82,101,116,117, + 114,110,115,32,40,108,111,97,100,101,114,44,32,108,105,115, + 116,45,111,102,45,112,111,114,116,105,111,110,115,41,46,10, + 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,85,115,101,32,102,105,110,100,95,115,112, + 101,99,40,41,32,105,110,115,116,101,97,100,46,10,10,32, + 32,32,32,32,32,32,32,78,41,3,114,203,0,0,0,114, + 140,0,0,0,114,178,0,0,0,41,3,114,118,0,0,0, + 114,139,0,0,0,114,187,0,0,0,114,5,0,0,0,114, + 5,0,0,0,114,8,0,0,0,114,137,0,0,0,119,5, + 0,0,115,8,0,0,0,0,7,10,1,8,1,8,1,122, + 22,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100, + 95,108,111,97,100,101,114,99,6,0,0,0,0,0,0,0, + 0,0,0,0,7,0,0,0,6,0,0,0,67,0,0,0, + 115,26,0,0,0,124,1,124,2,124,3,131,2,125,6,116, + 0,124,2,124,3,124,6,124,4,100,1,141,4,83,0,41, + 2,78,114,177,0,0,0,41,1,114,190,0,0,0,41,7, + 114,118,0,0,0,114,188,0,0,0,114,139,0,0,0,114, + 44,0,0,0,90,4,115,109,115,108,114,202,0,0,0,114, + 140,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,114,51,1,0,0,131,5,0,0,115,8,0,0, + 0,0,1,10,1,8,1,2,255,122,20,70,105,108,101,70, + 105,110,100,101,114,46,95,103,101,116,95,115,112,101,99,78, + 99,3,0,0,0,0,0,0,0,0,0,0,0,14,0,0, + 0,8,0,0,0,67,0,0,0,115,96,1,0,0,100,1, + 125,3,124,1,160,0,100,2,161,1,100,3,25,0,125,4, + 122,24,116,1,124,0,106,2,112,34,116,3,160,4,161,0, + 131,1,106,5,125,5,87,0,110,22,4,0,116,6,121,64, + 1,0,1,0,1,0,100,4,125,5,89,0,110,2,48,0, + 124,5,124,0,106,7,107,3,114,90,124,0,160,8,161,0, + 1,0,124,5,124,0,95,7,116,9,131,0,114,112,124,0, + 106,10,125,6,124,4,160,11,161,0,125,7,110,10,124,0, + 106,12,125,6,124,4,125,7,124,7,124,6,118,0,114,216, + 116,13,124,0,106,2,124,4,131,2,125,8,124,0,106,14, + 68,0,93,58,92,2,125,9,125,10,100,5,124,9,23,0, + 125,11,116,13,124,8,124,11,131,2,125,12,116,15,124,12, + 131,1,114,148,124,0,160,16,124,10,124,1,124,12,124,8, + 103,1,124,2,161,5,2,0,1,0,83,0,113,148,116,17, + 124,8,131,1,125,3,124,0,106,14,68,0,93,82,92,2, + 125,9,125,10,116,13,124,0,106,2,124,4,124,9,23,0, + 131,2,125,12,116,18,106,19,100,6,124,12,100,3,100,7, + 141,3,1,0,124,7,124,9,23,0,124,6,118,0,114,222, + 116,15,124,12,131,1,114,222,124,0,160,16,124,10,124,1, + 124,12,100,8,124,2,161,5,2,0,1,0,83,0,113,222, + 124,3,144,1,114,92,116,18,160,19,100,9,124,8,161,2, + 1,0,116,18,160,20,124,1,100,8,161,2,125,13,124,8, + 103,1,124,13,95,21,124,13,83,0,100,8,83,0,41,10, + 122,111,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 115,112,101,99,32,102,111,114,32,116,104,101,32,115,112,101, + 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,82,101,116,117,114,110,115,32, + 116,104,101,32,109,97,116,99,104,105,110,103,32,115,112,101, + 99,44,32,111,114,32,78,111,110,101,32,105,102,32,110,111, + 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, + 32,70,114,71,0,0,0,114,28,0,0,0,114,104,0,0, + 0,114,209,0,0,0,122,9,116,114,121,105,110,103,32,123, + 125,41,1,90,9,118,101,114,98,111,115,105,116,121,78,122, + 25,112,111,115,115,105,98,108,101,32,110,97,109,101,115,112, + 97,99,101,32,102,111,114,32,123,125,41,22,114,41,0,0, + 0,114,49,0,0,0,114,44,0,0,0,114,4,0,0,0, + 114,55,0,0,0,114,0,1,0,0,114,50,0,0,0,114, + 58,1,0,0,218,11,95,102,105,108,108,95,99,97,99,104, + 101,114,9,0,0,0,114,61,1,0,0,114,105,0,0,0, + 114,60,1,0,0,114,38,0,0,0,114,57,1,0,0,114, + 54,0,0,0,114,51,1,0,0,114,56,0,0,0,114,134, + 0,0,0,114,149,0,0,0,114,183,0,0,0,114,178,0, + 0,0,41,14,114,118,0,0,0,114,139,0,0,0,114,202, + 0,0,0,90,12,105,115,95,110,97,109,101,115,112,97,99, + 101,90,11,116,97,105,108,95,109,111,100,117,108,101,114,169, + 0,0,0,90,5,99,97,99,104,101,90,12,99,97,99,104, + 101,95,109,111,100,117,108,101,90,9,98,97,115,101,95,112, + 97,116,104,114,8,1,0,0,114,188,0,0,0,90,13,105, + 110,105,116,95,102,105,108,101,110,97,109,101,90,9,102,117, + 108,108,95,112,97,116,104,114,187,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,114,203,0,0,0, + 136,5,0,0,115,72,0,0,0,0,5,4,1,14,1,2, + 1,24,1,12,1,10,1,10,1,8,1,6,2,6,1,6, + 1,10,2,6,1,4,2,8,1,12,1,14,1,8,1,10, + 1,8,1,26,4,8,2,14,1,16,1,16,1,12,1,8, + 1,10,1,4,255,10,2,6,1,12,1,12,1,8,1,4, + 1,122,20,70,105,108,101,70,105,110,100,101,114,46,102,105, + 110,100,95,115,112,101,99,99,1,0,0,0,0,0,0,0, + 0,0,0,0,9,0,0,0,10,0,0,0,67,0,0,0, + 115,188,0,0,0,124,0,106,0,125,1,122,22,116,1,160, + 2,124,1,112,22,116,1,160,3,161,0,161,1,125,2,87, + 0,110,28,4,0,116,4,116,5,116,6,102,3,121,56,1, + 0,1,0,1,0,103,0,125,2,89,0,110,2,48,0,116, + 7,106,8,160,9,100,1,161,1,115,82,116,10,124,2,131, + 1,124,0,95,11,110,74,116,10,131,0,125,3,124,2,68, + 0,93,56,125,4,124,4,160,12,100,2,161,1,92,3,125, + 5,125,6,125,7,124,6,114,134,100,3,160,13,124,5,124, + 7,160,14,161,0,161,2,125,8,110,4,124,5,125,8,124, + 3,160,15,124,8,161,1,1,0,113,92,124,3,124,0,95, + 11,116,7,106,8,160,9,116,16,161,1,114,184,100,4,100, + 5,132,0,124,2,68,0,131,1,124,0,95,17,100,6,83, + 0,41,7,122,68,70,105,108,108,32,116,104,101,32,99,97, + 99,104,101,32,111,102,32,112,111,116,101,110,116,105,97,108, + 32,109,111,100,117,108,101,115,32,97,110,100,32,112,97,99, + 107,97,103,101,115,32,102,111,114,32,116,104,105,115,32,100, + 105,114,101,99,116,111,114,121,46,114,0,0,0,0,114,71, + 0,0,0,114,61,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,83,0,0, + 0,115,20,0,0,0,104,0,124,0,93,12,125,1,124,1, + 160,0,161,0,146,2,113,4,83,0,114,5,0,0,0,41, + 1,114,105,0,0,0,41,2,114,32,0,0,0,90,2,102, + 110,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, + 218,9,60,115,101,116,99,111,109,112,62,213,5,0,0,114, + 56,1,0,0,122,41,70,105,108,101,70,105,110,100,101,114, + 46,95,102,105,108,108,95,99,97,99,104,101,46,60,108,111, + 99,97,108,115,62,46,60,115,101,116,99,111,109,112,62,78, + 41,18,114,44,0,0,0,114,4,0,0,0,90,7,108,105, + 115,116,100,105,114,114,55,0,0,0,114,45,1,0,0,218, + 15,80,101,114,109,105,115,115,105,111,110,69,114,114,111,114, + 218,18,78,111,116,65,68,105,114,101,99,116,111,114,121,69, + 114,114,111,114,114,1,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,59,1,0,0,114,60,1,0,0,114,100,0, + 0,0,114,62,0,0,0,114,105,0,0,0,218,3,97,100, + 100,114,12,0,0,0,114,61,1,0,0,41,9,114,118,0, + 0,0,114,44,0,0,0,90,8,99,111,110,116,101,110,116, + 115,90,21,108,111,119,101,114,95,115,117,102,102,105,120,95, + 99,111,110,116,101,110,116,115,114,33,1,0,0,114,116,0, + 0,0,114,20,1,0,0,114,8,1,0,0,90,8,110,101, + 119,95,110,97,109,101,114,5,0,0,0,114,5,0,0,0, + 114,8,0,0,0,114,63,1,0,0,184,5,0,0,115,34, + 0,0,0,0,2,6,1,2,1,22,1,18,3,10,3,12, + 1,12,7,6,1,8,1,16,1,4,1,18,2,4,1,12, + 1,6,1,12,1,122,22,70,105,108,101,70,105,110,100,101, + 114,46,95,102,105,108,108,95,99,97,99,104,101,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,7,0,0,0,115,18,0,0,0,135,0,135,1,102, + 2,100,1,100,2,132,8,125,2,124,2,83,0,41,3,97, + 20,1,0,0,65,32,99,108,97,115,115,32,109,101,116,104, + 111,100,32,119,104,105,99,104,32,114,101,116,117,114,110,115, + 32,97,32,99,108,111,115,117,114,101,32,116,111,32,117,115, + 101,32,111,110,32,115,121,115,46,112,97,116,104,95,104,111, + 111,107,10,32,32,32,32,32,32,32,32,119,104,105,99,104, + 32,119,105,108,108,32,114,101,116,117,114,110,32,97,110,32, + 105,110,115,116,97,110,99,101,32,117,115,105,110,103,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,108,111,97, + 100,101,114,115,32,97,110,100,32,116,104,101,32,112,97,116, + 104,10,32,32,32,32,32,32,32,32,99,97,108,108,101,100, + 32,111,110,32,116,104,101,32,99,108,111,115,117,114,101,46, + 10,10,32,32,32,32,32,32,32,32,73,102,32,116,104,101, + 32,112,97,116,104,32,99,97,108,108,101,100,32,111,110,32, + 116,104,101,32,99,108,111,115,117,114,101,32,105,115,32,110, + 111,116,32,97,32,100,105,114,101,99,116,111,114,121,44,32, + 73,109,112,111,114,116,69,114,114,111,114,32,105,115,10,32, + 32,32,32,32,32,32,32,114,97,105,115,101,100,46,10,10, + 32,32,32,32,32,32,32,32,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,19,0,0, + 0,115,36,0,0,0,116,0,124,0,131,1,115,20,116,1, + 100,1,124,0,100,2,141,2,130,1,136,0,124,0,103,1, + 136,1,162,1,82,0,142,0,83,0,41,3,122,45,80,97, + 116,104,32,104,111,111,107,32,102,111,114,32,105,109,112,111, + 114,116,108,105,98,46,109,97,99,104,105,110,101,114,121,46, + 70,105,108,101,70,105,110,100,101,114,46,122,30,111,110,108, + 121,32,100,105,114,101,99,116,111,114,105,101,115,32,97,114, + 101,32,115,117,112,112,111,114,116,101,100,114,48,0,0,0, + 41,2,114,56,0,0,0,114,117,0,0,0,114,48,0,0, + 0,169,2,114,193,0,0,0,114,62,1,0,0,114,5,0, + 0,0,114,8,0,0,0,218,24,112,97,116,104,95,104,111, + 111,107,95,102,111,114,95,70,105,108,101,70,105,110,100,101, + 114,225,5,0,0,115,6,0,0,0,0,2,8,1,12,1, + 122,54,70,105,108,101,70,105,110,100,101,114,46,112,97,116, + 104,95,104,111,111,107,46,60,108,111,99,97,108,115,62,46, + 112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105, + 108,101,70,105,110,100,101,114,114,5,0,0,0,41,3,114, + 193,0,0,0,114,62,1,0,0,114,69,1,0,0,114,5, + 0,0,0,114,68,1,0,0,114,8,0,0,0,218,9,112, + 97,116,104,95,104,111,111,107,215,5,0,0,115,4,0,0, + 0,0,10,14,6,122,20,70,105,108,101,70,105,110,100,101, + 114,46,112,97,116,104,95,104,111,111,107,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, + 67,0,0,0,115,12,0,0,0,100,1,160,0,124,0,106, + 1,161,1,83,0,41,2,78,122,16,70,105,108,101,70,105, + 110,100,101,114,40,123,33,114,125,41,41,2,114,62,0,0, + 0,114,44,0,0,0,114,246,0,0,0,114,5,0,0,0, + 114,5,0,0,0,114,8,0,0,0,114,31,1,0,0,233, + 5,0,0,115,2,0,0,0,0,1,122,19,70,105,108,101, + 70,105,110,100,101,114,46,95,95,114,101,112,114,95,95,41, + 1,78,41,15,114,125,0,0,0,114,124,0,0,0,114,126, + 0,0,0,114,127,0,0,0,114,209,0,0,0,114,38,1, + 0,0,114,143,0,0,0,114,206,0,0,0,114,137,0,0, + 0,114,51,1,0,0,114,203,0,0,0,114,63,1,0,0, + 114,207,0,0,0,114,70,1,0,0,114,31,1,0,0,114, + 5,0,0,0,114,5,0,0,0,114,5,0,0,0,114,8, + 0,0,0,114,54,1,0,0,90,5,0,0,115,22,0,0, + 0,8,2,4,7,8,14,8,4,4,2,8,12,8,5,10, + 48,8,31,2,1,10,17,114,54,1,0,0,99,4,0,0, + 0,0,0,0,0,0,0,0,0,6,0,0,0,8,0,0, + 0,67,0,0,0,115,144,0,0,0,124,0,160,0,100,1, + 161,1,125,4,124,0,160,0,100,2,161,1,125,5,124,4, + 115,66,124,5,114,36,124,5,106,1,125,4,110,30,124,2, + 124,3,107,2,114,56,116,2,124,1,124,2,131,2,125,4, + 110,10,116,3,124,1,124,2,131,2,125,4,124,5,115,84, + 116,4,124,1,124,2,124,4,100,3,141,3,125,5,122,36, + 124,5,124,0,100,2,60,0,124,4,124,0,100,1,60,0, + 124,2,124,0,100,4,60,0,124,3,124,0,100,5,60,0, + 87,0,110,18,4,0,116,5,121,138,1,0,1,0,1,0, + 89,0,110,2,48,0,100,0,83,0,41,6,78,218,10,95, + 95,108,111,97,100,101,114,95,95,218,8,95,95,115,112,101, + 99,95,95,114,55,1,0,0,90,8,95,95,102,105,108,101, + 95,95,90,10,95,95,99,97,99,104,101,100,95,95,41,6, + 218,3,103,101,116,114,140,0,0,0,114,5,1,0,0,114, + 255,0,0,0,114,190,0,0,0,218,9,69,120,99,101,112, + 116,105,111,110,41,6,90,2,110,115,114,116,0,0,0,90, + 8,112,97,116,104,110,97,109,101,90,9,99,112,97,116,104, + 110,97,109,101,114,140,0,0,0,114,187,0,0,0,114,5, + 0,0,0,114,5,0,0,0,114,8,0,0,0,218,14,95, + 102,105,120,95,117,112,95,109,111,100,117,108,101,239,5,0, + 0,115,34,0,0,0,0,2,10,1,10,1,4,1,4,1, + 8,1,8,1,12,2,10,1,4,1,14,1,2,1,8,1, + 8,1,8,1,12,1,12,2,114,75,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,38,0,0,0,116,0,116,1,160, + 2,161,0,102,2,125,0,116,3,116,4,102,2,125,1,116, + 5,116,6,102,2,125,2,124,0,124,1,124,2,103,3,83, + 0,41,1,122,95,82,101,116,117,114,110,115,32,97,32,108, + 105,115,116,32,111,102,32,102,105,108,101,45,98,97,115,101, + 100,32,109,111,100,117,108,101,32,108,111,97,100,101,114,115, + 46,10,10,32,32,32,32,69,97,99,104,32,105,116,101,109, + 32,105,115,32,97,32,116,117,112,108,101,32,40,108,111,97, + 100,101,114,44,32,115,117,102,102,105,120,101,115,41,46,10, + 32,32,32,32,41,7,114,252,0,0,0,114,163,0,0,0, + 218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102, + 105,120,101,115,114,255,0,0,0,114,101,0,0,0,114,5, + 1,0,0,114,88,0,0,0,41,3,90,10,101,120,116,101, + 110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8, + 98,121,116,101,99,111,100,101,114,5,0,0,0,114,5,0, + 0,0,114,8,0,0,0,114,184,0,0,0,6,6,0,0, + 115,8,0,0,0,0,5,12,1,8,1,8,1,114,184,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,10, + 0,0,0,9,0,0,0,67,0,0,0,115,132,1,0,0, + 124,0,97,0,116,0,106,1,97,1,116,0,106,2,97,2, + 116,1,106,3,116,4,25,0,125,1,100,1,100,2,103,1, + 102,2,100,3,100,4,100,2,103,2,102,2,102,2,125,2, + 124,2,68,0,93,108,92,2,125,3,125,4,116,5,100,5, + 100,6,132,0,124,4,68,0,131,1,131,1,115,82,74,0, + 130,1,124,4,100,7,25,0,125,5,124,3,116,1,106,3, + 118,0,114,116,116,1,106,3,124,3,25,0,125,6,1,0, + 113,170,113,52,122,20,116,0,160,6,124,3,161,1,125,6, + 87,0,1,0,113,170,87,0,113,52,4,0,116,7,121,158, + 1,0,1,0,1,0,89,0,113,52,89,0,113,52,48,0, + 113,52,116,7,100,8,131,1,130,1,116,8,124,1,100,9, + 124,6,131,3,1,0,116,8,124,1,100,10,124,5,131,3, + 1,0,116,8,124,1,100,11,100,12,160,9,124,4,161,1, + 131,3,1,0,116,8,124,1,100,13,100,14,100,15,132,0, + 124,4,68,0,131,1,131,3,1,0,103,0,100,16,162,1, + 125,7,124,3,100,3,107,2,144,1,114,6,124,7,160,10, + 100,17,161,1,1,0,124,7,68,0,93,52,125,8,124,8, + 116,1,106,3,118,1,144,1,114,38,116,0,160,6,124,8, + 161,1,125,9,110,10,116,1,106,3,124,8,25,0,125,9, + 116,8,124,1,124,8,124,9,131,3,1,0,144,1,113,10, + 116,8,124,1,100,18,116,11,131,0,131,3,1,0,116,12, + 160,13,116,2,160,14,161,0,161,1,1,0,124,3,100,3, + 107,2,144,1,114,128,116,15,160,10,100,19,161,1,1,0, + 100,20,116,12,118,0,144,1,114,128,100,21,116,16,95,17, + 100,22,83,0,41,23,122,205,83,101,116,117,112,32,116,104, + 101,32,112,97,116,104,45,98,97,115,101,100,32,105,109,112, + 111,114,116,101,114,115,32,102,111,114,32,105,109,112,111,114, + 116,108,105,98,32,98,121,32,105,109,112,111,114,116,105,110, + 103,32,110,101,101,100,101,100,10,32,32,32,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,110, + 100,32,105,110,106,101,99,116,105,110,103,32,116,104,101,109, + 32,105,110,116,111,32,116,104,101,32,103,108,111,98,97,108, + 32,110,97,109,101,115,112,97,99,101,46,10,10,32,32,32, + 32,79,116,104,101,114,32,99,111,109,112,111,110,101,110,116, + 115,32,97,114,101,32,101,120,116,114,97,99,116,101,100,32, + 102,114,111,109,32,116,104,101,32,99,111,114,101,32,98,111, + 111,116,115,116,114,97,112,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,90,5,112,111,115,105,120,250,1,47,90, + 2,110,116,250,1,92,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,115,0,0,0,115, + 26,0,0,0,124,0,93,18,125,1,116,0,124,1,131,1, + 100,0,107,2,86,0,1,0,113,2,100,1,83,0,41,2, + 114,39,0,0,0,78,41,1,114,23,0,0,0,41,2,114, + 32,0,0,0,114,94,0,0,0,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,10,1,0,0,35,6,0, + 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, + 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, + 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, + 98,32,114,101,113,117,105,114,101,115,32,112,111,115,105,120, + 32,111,114,32,110,116,114,4,0,0,0,114,35,0,0,0, + 114,31,0,0,0,114,40,0,0,0,114,58,0,0,0,99, 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,51,0,0,0,115,22,0,0,0,124,0,93, - 14,125,1,124,1,136,0,102,2,86,0,1,0,113,2,100, - 0,83,0,114,109,0,0,0,114,5,0,0,0,114,16,1, - 0,0,169,1,114,140,0,0,0,114,5,0,0,0,114,8, - 0,0,0,114,19,1,0,0,127,5,0,0,243,0,0,0, - 0,122,38,70,105,108,101,70,105,110,100,101,114,46,95,95, - 105,110,105,116,95,95,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,114,71,0,0,0,114,104, - 0,0,0,78,41,7,114,167,0,0,0,218,8,95,108,111, - 97,100,101,114,115,114,44,0,0,0,218,11,95,112,97,116, - 104,95,109,116,105,109,101,218,3,115,101,116,218,11,95,112, - 97,116,104,95,99,97,99,104,101,218,19,95,114,101,108,97, - 120,101,100,95,112,97,116,104,95,99,97,99,104,101,41,5, - 114,118,0,0,0,114,44,0,0,0,218,14,108,111,97,100, - 101,114,95,100,101,116,97,105,108,115,90,7,108,111,97,100, - 101,114,115,114,189,0,0,0,114,5,0,0,0,114,62,1, - 0,0,114,8,0,0,0,114,209,0,0,0,121,5,0,0, - 115,16,0,0,0,0,4,4,1,12,1,26,1,6,2,10, - 1,6,1,8,1,122,19,70,105,108,101,70,105,110,100,101, - 114,46,95,95,105,110,105,116,95,95,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, - 0,0,0,115,10,0,0,0,100,1,124,0,95,0,100,2, - 83,0,41,3,122,31,73,110,118,97,108,105,100,97,116,101, - 32,116,104,101,32,100,105,114,101,99,116,111,114,121,32,109, - 116,105,109,101,46,114,104,0,0,0,78,41,1,114,65,1, - 0,0,114,246,0,0,0,114,5,0,0,0,114,5,0,0, - 0,114,8,0,0,0,114,46,1,0,0,135,5,0,0,115, - 2,0,0,0,0,2,122,28,70,105,108,101,70,105,110,100, - 101,114,46,105,110,118,97,108,105,100,97,116,101,95,99,97, - 99,104,101,115,99,2,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,42,0, - 0,0,124,0,160,0,124,1,161,1,125,2,124,2,100,1, - 117,0,114,26,100,1,103,0,102,2,83,0,124,2,106,1, - 124,2,106,2,112,38,103,0,102,2,83,0,41,2,122,197, - 84,114,121,32,116,111,32,102,105,110,100,32,97,32,108,111, - 97,100,101,114,32,102,111,114,32,116,104,101,32,115,112,101, - 99,105,102,105,101,100,32,109,111,100,117,108,101,44,32,111, - 114,32,116,104,101,32,110,97,109,101,115,112,97,99,101,10, - 32,32,32,32,32,32,32,32,112,97,99,107,97,103,101,32, - 112,111,114,116,105,111,110,115,46,32,82,101,116,117,114,110, - 115,32,40,108,111,97,100,101,114,44,32,108,105,115,116,45, - 111,102,45,112,111,114,116,105,111,110,115,41,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,78,41,3,114,203,0,0,0,114,140,0, - 0,0,114,178,0,0,0,41,3,114,118,0,0,0,114,139, - 0,0,0,114,187,0,0,0,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,114,137,0,0,0,141,5,0,0, - 115,8,0,0,0,0,7,10,1,8,1,8,1,122,22,70, - 105,108,101,70,105,110,100,101,114,46,102,105,110,100,95,108, - 111,97,100,101,114,99,6,0,0,0,0,0,0,0,0,0, - 0,0,7,0,0,0,6,0,0,0,67,0,0,0,115,26, - 0,0,0,124,1,124,2,124,3,131,2,125,6,116,0,124, - 2,124,3,124,6,124,4,100,1,141,4,83,0,41,2,78, - 114,177,0,0,0,41,1,114,190,0,0,0,41,7,114,118, - 0,0,0,114,188,0,0,0,114,139,0,0,0,114,44,0, - 0,0,90,4,115,109,115,108,114,202,0,0,0,114,140,0, - 0,0,114,5,0,0,0,114,5,0,0,0,114,8,0,0, - 0,114,58,1,0,0,153,5,0,0,115,8,0,0,0,0, - 1,10,1,8,1,2,255,122,20,70,105,108,101,70,105,110, - 100,101,114,46,95,103,101,116,95,115,112,101,99,78,99,3, - 0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,8, - 0,0,0,67,0,0,0,115,96,1,0,0,100,1,125,3, - 124,1,160,0,100,2,161,1,100,3,25,0,125,4,122,24, - 116,1,124,0,106,2,112,34,116,3,160,4,161,0,131,1, - 106,5,125,5,87,0,110,22,4,0,116,6,121,64,1,0, - 1,0,1,0,100,4,125,5,89,0,110,2,48,0,124,5, - 124,0,106,7,107,3,114,90,124,0,160,8,161,0,1,0, - 124,5,124,0,95,7,116,9,131,0,114,112,124,0,106,10, - 125,6,124,4,160,11,161,0,125,7,110,10,124,0,106,12, - 125,6,124,4,125,7,124,7,124,6,118,0,114,216,116,13, - 124,0,106,2,124,4,131,2,125,8,124,0,106,14,68,0, - 93,58,92,2,125,9,125,10,100,5,124,9,23,0,125,11, - 116,13,124,8,124,11,131,2,125,12,116,15,124,12,131,1, - 114,148,124,0,160,16,124,10,124,1,124,12,124,8,103,1, - 124,2,161,5,2,0,1,0,83,0,113,148,116,17,124,8, - 131,1,125,3,124,0,106,14,68,0,93,82,92,2,125,9, - 125,10,116,13,124,0,106,2,124,4,124,9,23,0,131,2, - 125,12,116,18,106,19,100,6,124,12,100,3,100,7,141,3, - 1,0,124,7,124,9,23,0,124,6,118,0,114,222,116,15, - 124,12,131,1,114,222,124,0,160,16,124,10,124,1,124,12, - 100,8,124,2,161,5,2,0,1,0,83,0,113,222,124,3, - 144,1,114,92,116,18,160,19,100,9,124,8,161,2,1,0, - 116,18,160,20,124,1,100,8,161,2,125,13,124,8,103,1, - 124,13,95,21,124,13,83,0,100,8,83,0,41,10,122,111, - 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, - 101,99,32,102,111,114,32,116,104,101,32,115,112,101,99,105, - 102,105,101,100,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,32,32,32,32,82,101,116,117,114,110,115,32,116,104, - 101,32,109,97,116,99,104,105,110,103,32,115,112,101,99,44, - 32,111,114,32,78,111,110,101,32,105,102,32,110,111,116,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,70, - 114,71,0,0,0,114,28,0,0,0,114,104,0,0,0,114, - 209,0,0,0,122,9,116,114,121,105,110,103,32,123,125,41, - 1,90,9,118,101,114,98,111,115,105,116,121,78,122,25,112, - 111,115,115,105,98,108,101,32,110,97,109,101,115,112,97,99, - 101,32,102,111,114,32,123,125,41,22,114,41,0,0,0,114, - 49,0,0,0,114,44,0,0,0,114,4,0,0,0,114,55, - 0,0,0,114,10,1,0,0,114,50,0,0,0,114,65,1, - 0,0,218,11,95,102,105,108,108,95,99,97,99,104,101,114, - 9,0,0,0,114,68,1,0,0,114,105,0,0,0,114,67, - 1,0,0,114,38,0,0,0,114,64,1,0,0,114,54,0, - 0,0,114,58,1,0,0,114,56,0,0,0,114,134,0,0, - 0,114,149,0,0,0,114,183,0,0,0,114,178,0,0,0, - 41,14,114,118,0,0,0,114,139,0,0,0,114,202,0,0, - 0,90,12,105,115,95,110,97,109,101,115,112,97,99,101,90, - 11,116,97,105,108,95,109,111,100,117,108,101,114,169,0,0, - 0,90,5,99,97,99,104,101,90,12,99,97,99,104,101,95, - 109,111,100,117,108,101,90,9,98,97,115,101,95,112,97,116, - 104,114,17,1,0,0,114,188,0,0,0,90,13,105,110,105, - 116,95,102,105,108,101,110,97,109,101,90,9,102,117,108,108, - 95,112,97,116,104,114,187,0,0,0,114,5,0,0,0,114, - 5,0,0,0,114,8,0,0,0,114,203,0,0,0,158,5, - 0,0,115,72,0,0,0,0,5,4,1,14,1,2,1,24, - 1,12,1,10,1,10,1,8,1,6,2,6,1,6,1,10, - 2,6,1,4,2,8,1,12,1,14,1,8,1,10,1,8, - 1,26,4,8,2,14,1,16,1,16,1,12,1,8,1,10, - 1,4,255,10,2,6,1,12,1,12,1,8,1,4,1,122, - 20,70,105,108,101,70,105,110,100,101,114,46,102,105,110,100, - 95,115,112,101,99,99,1,0,0,0,0,0,0,0,0,0, - 0,0,9,0,0,0,10,0,0,0,67,0,0,0,115,188, - 0,0,0,124,0,106,0,125,1,122,22,116,1,160,2,124, - 1,112,22,116,1,160,3,161,0,161,1,125,2,87,0,110, - 28,4,0,116,4,116,5,116,6,102,3,121,56,1,0,1, - 0,1,0,103,0,125,2,89,0,110,2,48,0,116,7,106, - 8,160,9,100,1,161,1,115,82,116,10,124,2,131,1,124, - 0,95,11,110,74,116,10,131,0,125,3,124,2,68,0,93, - 56,125,4,124,4,160,12,100,2,161,1,92,3,125,5,125, - 6,125,7,124,6,114,134,100,3,160,13,124,5,124,7,160, - 14,161,0,161,2,125,8,110,4,124,5,125,8,124,3,160, - 15,124,8,161,1,1,0,113,92,124,3,124,0,95,11,116, - 7,106,8,160,9,116,16,161,1,114,184,100,4,100,5,132, - 0,124,2,68,0,131,1,124,0,95,17,100,6,83,0,41, - 7,122,68,70,105,108,108,32,116,104,101,32,99,97,99,104, - 101,32,111,102,32,112,111,116,101,110,116,105,97,108,32,109, - 111,100,117,108,101,115,32,97,110,100,32,112,97,99,107,97, - 103,101,115,32,102,111,114,32,116,104,105,115,32,100,105,114, - 101,99,116,111,114,121,46,114,0,0,0,0,114,71,0,0, - 0,114,61,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,83,0,0,0,115, - 20,0,0,0,104,0,124,0,93,12,125,1,124,1,160,0, - 161,0,146,2,113,4,83,0,114,5,0,0,0,41,1,114, - 105,0,0,0,41,2,114,32,0,0,0,90,2,102,110,114, - 5,0,0,0,114,5,0,0,0,114,8,0,0,0,218,9, - 60,115,101,116,99,111,109,112,62,235,5,0,0,114,63,1, - 0,0,122,41,70,105,108,101,70,105,110,100,101,114,46,95, - 102,105,108,108,95,99,97,99,104,101,46,60,108,111,99,97, - 108,115,62,46,60,115,101,116,99,111,109,112,62,78,41,18, - 114,44,0,0,0,114,4,0,0,0,114,7,1,0,0,114, - 55,0,0,0,114,3,1,0,0,218,15,80,101,114,109,105, - 115,115,105,111,110,69,114,114,111,114,218,18,78,111,116,65, - 68,105,114,101,99,116,111,114,121,69,114,114,111,114,114,1, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,66,1, - 0,0,114,67,1,0,0,114,100,0,0,0,114,62,0,0, - 0,114,105,0,0,0,218,3,97,100,100,114,12,0,0,0, - 114,68,1,0,0,41,9,114,118,0,0,0,114,44,0,0, - 0,114,8,1,0,0,90,21,108,111,119,101,114,95,115,117, - 102,102,105,120,95,99,111,110,116,101,110,116,115,114,41,1, - 0,0,114,116,0,0,0,114,29,1,0,0,114,17,1,0, - 0,90,8,110,101,119,95,110,97,109,101,114,5,0,0,0, - 114,5,0,0,0,114,8,0,0,0,114,70,1,0,0,206, - 5,0,0,115,34,0,0,0,0,2,6,1,2,1,22,1, - 18,3,10,3,12,1,12,7,6,1,8,1,16,1,4,1, - 18,2,4,1,12,1,6,1,12,1,122,22,70,105,108,101, - 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, - 104,101,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,7,0,0,0,115,18,0,0,0, - 135,0,135,1,102,2,100,1,100,2,132,8,125,2,124,2, - 83,0,41,3,97,20,1,0,0,65,32,99,108,97,115,115, - 32,109,101,116,104,111,100,32,119,104,105,99,104,32,114,101, - 116,117,114,110,115,32,97,32,99,108,111,115,117,114,101,32, - 116,111,32,117,115,101,32,111,110,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,10,32,32,32,32,32,32,32,32, - 119,104,105,99,104,32,119,105,108,108,32,114,101,116,117,114, - 110,32,97,110,32,105,110,115,116,97,110,99,101,32,117,115, - 105,110,103,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,108,111,97,100,101,114,115,32,97,110,100,32,116,104, - 101,32,112,97,116,104,10,32,32,32,32,32,32,32,32,99, - 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, - 115,117,114,101,46,10,10,32,32,32,32,32,32,32,32,73, - 102,32,116,104,101,32,112,97,116,104,32,99,97,108,108,101, - 100,32,111,110,32,116,104,101,32,99,108,111,115,117,114,101, - 32,105,115,32,110,111,116,32,97,32,100,105,114,101,99,116, - 111,114,121,44,32,73,109,112,111,114,116,69,114,114,111,114, - 32,105,115,10,32,32,32,32,32,32,32,32,114,97,105,115, - 101,100,46,10,10,32,32,32,32,32,32,32,32,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,19,0,0,0,115,36,0,0,0,116,0,124,0,131, - 1,115,20,116,1,100,1,124,0,100,2,141,2,130,1,136, - 0,124,0,103,1,136,1,162,1,82,0,142,0,83,0,41, - 3,122,45,80,97,116,104,32,104,111,111,107,32,102,111,114, - 32,105,109,112,111,114,116,108,105,98,46,109,97,99,104,105, - 110,101,114,121,46,70,105,108,101,70,105,110,100,101,114,46, - 122,30,111,110,108,121,32,100,105,114,101,99,116,111,114,105, - 101,115,32,97,114,101,32,115,117,112,112,111,114,116,101,100, - 114,48,0,0,0,41,2,114,56,0,0,0,114,117,0,0, - 0,114,48,0,0,0,169,2,114,193,0,0,0,114,69,1, - 0,0,114,5,0,0,0,114,8,0,0,0,218,24,112,97, - 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, - 70,105,110,100,101,114,247,5,0,0,115,6,0,0,0,0, - 2,8,1,12,1,122,54,70,105,108,101,70,105,110,100,101, - 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, - 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,114,5,0, - 0,0,41,3,114,193,0,0,0,114,69,1,0,0,114,76, - 1,0,0,114,5,0,0,0,114,75,1,0,0,114,8,0, - 0,0,218,9,112,97,116,104,95,104,111,111,107,237,5,0, - 0,115,4,0,0,0,0,10,14,6,122,20,70,105,108,101, - 70,105,110,100,101,114,46,112,97,116,104,95,104,111,111,107, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,12,0,0,0,100,1, - 160,0,124,0,106,1,161,1,83,0,41,2,78,122,16,70, - 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, - 2,114,62,0,0,0,114,44,0,0,0,114,246,0,0,0, - 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,114, - 39,1,0,0,255,5,0,0,115,2,0,0,0,0,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,114,101, - 112,114,95,95,41,1,78,41,15,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,209,0, - 0,0,114,46,1,0,0,114,143,0,0,0,114,206,0,0, - 0,114,137,0,0,0,114,58,1,0,0,114,203,0,0,0, - 114,70,1,0,0,114,207,0,0,0,114,77,1,0,0,114, - 39,1,0,0,114,5,0,0,0,114,5,0,0,0,114,5, - 0,0,0,114,8,0,0,0,114,61,1,0,0,112,5,0, - 0,115,22,0,0,0,8,2,4,7,8,14,8,4,4,2, - 8,12,8,5,10,48,8,31,2,1,10,17,114,61,1,0, - 0,99,4,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,8,0,0,0,67,0,0,0,115,144,0,0,0,124, - 0,160,0,100,1,161,1,125,4,124,0,160,0,100,2,161, - 1,125,5,124,4,115,66,124,5,114,36,124,5,106,1,125, - 4,110,30,124,2,124,3,107,2,114,56,116,2,124,1,124, - 2,131,2,125,4,110,10,116,3,124,1,124,2,131,2,125, - 4,124,5,115,84,116,4,124,1,124,2,124,4,100,3,141, - 3,125,5,122,36,124,5,124,0,100,2,60,0,124,4,124, - 0,100,1,60,0,124,2,124,0,100,4,60,0,124,3,124, - 0,100,5,60,0,87,0,110,18,4,0,116,5,121,138,1, - 0,1,0,1,0,89,0,110,2,48,0,100,0,83,0,41, - 6,78,218,10,95,95,108,111,97,100,101,114,95,95,218,8, - 95,95,115,112,101,99,95,95,114,62,1,0,0,90,8,95, - 95,102,105,108,101,95,95,90,10,95,95,99,97,99,104,101, - 100,95,95,41,6,218,3,103,101,116,114,140,0,0,0,114, - 15,1,0,0,114,9,1,0,0,114,190,0,0,0,218,9, - 69,120,99,101,112,116,105,111,110,41,6,90,2,110,115,114, - 116,0,0,0,90,8,112,97,116,104,110,97,109,101,90,9, - 99,112,97,116,104,110,97,109,101,114,140,0,0,0,114,187, - 0,0,0,114,5,0,0,0,114,5,0,0,0,114,8,0, - 0,0,218,14,95,102,105,120,95,117,112,95,109,111,100,117, - 108,101,5,6,0,0,115,34,0,0,0,0,2,10,1,10, - 1,4,1,4,1,8,1,8,1,12,2,10,1,4,1,14, - 1,2,1,8,1,8,1,8,1,12,1,12,2,114,82,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 116,0,116,1,160,2,161,0,102,2,125,0,116,3,116,4, - 102,2,125,1,116,5,116,6,102,2,125,2,124,0,124,1, - 124,2,103,3,83,0,41,1,122,95,82,101,116,117,114,110, - 115,32,97,32,108,105,115,116,32,111,102,32,102,105,108,101, - 45,98,97,115,101,100,32,109,111,100,117,108,101,32,108,111, - 97,100,101,114,115,46,10,10,32,32,32,32,69,97,99,104, - 32,105,116,101,109,32,105,115,32,97,32,116,117,112,108,101, - 32,40,108,111,97,100,101,114,44,32,115,117,102,102,105,120, - 101,115,41,46,10,32,32,32,32,41,7,114,252,0,0,0, - 114,163,0,0,0,218,18,101,120,116,101,110,115,105,111,110, - 95,115,117,102,102,105,120,101,115,114,9,1,0,0,114,101, - 0,0,0,114,15,1,0,0,114,88,0,0,0,41,3,90, - 10,101,120,116,101,110,115,105,111,110,115,90,6,115,111,117, - 114,99,101,90,8,98,121,116,101,99,111,100,101,114,5,0, - 0,0,114,5,0,0,0,114,8,0,0,0,114,184,0,0, - 0,28,6,0,0,115,8,0,0,0,0,5,12,1,8,1, - 8,1,114,184,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,10,0,0,0,9,0,0,0,67,0,0,0, - 115,132,1,0,0,124,0,97,0,116,0,106,1,97,1,116, - 0,106,2,97,2,116,1,106,3,116,4,25,0,125,1,100, - 1,100,2,103,1,102,2,100,3,100,4,100,2,103,2,102, - 2,102,2,125,2,124,2,68,0,93,108,92,2,125,3,125, - 4,116,5,100,5,100,6,132,0,124,4,68,0,131,1,131, - 1,115,82,74,0,130,1,124,4,100,7,25,0,125,5,124, - 3,116,1,106,3,118,0,114,116,116,1,106,3,124,3,25, - 0,125,6,1,0,113,170,113,52,122,20,116,0,160,6,124, - 3,161,1,125,6,87,0,1,0,113,170,87,0,113,52,4, - 0,116,7,121,158,1,0,1,0,1,0,89,0,113,52,89, - 0,113,52,48,0,113,52,116,7,100,8,131,1,130,1,116, - 8,124,1,100,9,124,6,131,3,1,0,116,8,124,1,100, - 10,124,5,131,3,1,0,116,8,124,1,100,11,100,12,160, - 9,124,4,161,1,131,3,1,0,116,8,124,1,100,13,100, - 14,100,15,132,0,124,4,68,0,131,1,131,3,1,0,103, - 0,100,16,162,1,125,7,124,3,100,3,107,2,144,1,114, - 6,124,7,160,10,100,17,161,1,1,0,124,7,68,0,93, - 52,125,8,124,8,116,1,106,3,118,1,144,1,114,38,116, - 0,160,6,124,8,161,1,125,9,110,10,116,1,106,3,124, - 8,25,0,125,9,116,8,124,1,124,8,124,9,131,3,1, - 0,144,1,113,10,116,8,124,1,100,18,116,11,131,0,131, - 3,1,0,116,12,160,13,116,2,160,14,161,0,161,1,1, - 0,124,3,100,3,107,2,144,1,114,128,116,15,160,10,100, - 19,161,1,1,0,100,20,116,12,118,0,144,1,114,128,100, - 21,116,16,95,17,100,22,83,0,41,23,122,205,83,101,116, - 117,112,32,116,104,101,32,112,97,116,104,45,98,97,115,101, - 100,32,105,109,112,111,114,116,101,114,115,32,102,111,114,32, - 105,109,112,111,114,116,108,105,98,32,98,121,32,105,109,112, - 111,114,116,105,110,103,32,110,101,101,100,101,100,10,32,32, - 32,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,115,32,97,110,100,32,105,110,106,101,99,116,105,110,103, - 32,116,104,101,109,32,105,110,116,111,32,116,104,101,32,103, - 108,111,98,97,108,32,110,97,109,101,115,112,97,99,101,46, - 10,10,32,32,32,32,79,116,104,101,114,32,99,111,109,112, - 111,110,101,110,116,115,32,97,114,101,32,101,120,116,114,97, - 99,116,101,100,32,102,114,111,109,32,116,104,101,32,99,111, - 114,101,32,98,111,111,116,115,116,114,97,112,32,109,111,100, - 117,108,101,46,10,10,32,32,32,32,90,5,112,111,115,105, - 120,250,1,47,90,2,110,116,250,1,92,99,1,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 115,0,0,0,115,26,0,0,0,124,0,93,18,125,1,116, - 0,124,1,131,1,100,0,107,2,86,0,1,0,113,2,100, - 1,83,0,41,2,114,39,0,0,0,78,41,1,114,23,0, - 0,0,41,2,114,32,0,0,0,114,94,0,0,0,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,19,1, - 0,0,57,6,0,0,114,63,1,0,0,122,25,95,115,101, - 116,117,112,46,60,108,111,99,97,108,115,62,46,60,103,101, - 110,101,120,112,114,62,114,73,0,0,0,122,30,105,109,112, - 111,114,116,108,105,98,32,114,101,113,117,105,114,101,115,32, - 112,111,115,105,120,32,111,114,32,110,116,114,4,0,0,0, - 114,35,0,0,0,114,31,0,0,0,114,40,0,0,0,114, - 58,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,83,0,0,0,115,22,0, - 0,0,104,0,124,0,93,14,125,1,100,0,124,1,155,0, - 157,2,146,2,113,4,83,0,41,1,114,74,0,0,0,114, - 5,0,0,0,41,2,114,32,0,0,0,218,1,115,114,5, - 0,0,0,114,5,0,0,0,114,8,0,0,0,114,71,1, - 0,0,74,6,0,0,114,63,1,0,0,122,25,95,115,101, - 116,117,112,46,60,108,111,99,97,108,115,62,46,60,115,101, - 116,99,111,109,112,62,41,3,114,64,0,0,0,114,75,0, - 0,0,114,160,0,0,0,114,192,0,0,0,114,9,0,0, - 0,122,4,46,112,121,119,122,6,95,100,46,112,121,100,84, - 78,41,18,114,134,0,0,0,114,1,0,0,0,114,163,0, - 0,0,114,31,1,0,0,114,125,0,0,0,218,3,97,108, - 108,90,18,95,98,117,105,108,116,105,110,95,102,114,111,109, - 95,110,97,109,101,114,117,0,0,0,114,129,0,0,0,114, - 36,0,0,0,114,186,0,0,0,114,14,0,0,0,114,21, - 1,0,0,114,167,0,0,0,114,83,1,0,0,114,101,0, - 0,0,114,191,0,0,0,114,195,0,0,0,41,10,218,17, - 95,98,111,111,116,115,116,114,97,112,95,109,111,100,117,108, - 101,90,11,115,101,108,102,95,109,111,100,117,108,101,90,10, - 111,115,95,100,101,116,97,105,108,115,90,10,98,117,105,108, - 116,105,110,95,111,115,114,31,0,0,0,114,35,0,0,0, - 90,9,111,115,95,109,111,100,117,108,101,90,13,98,117,105, - 108,116,105,110,95,110,97,109,101,115,90,12,98,117,105,108, - 116,105,110,95,110,97,109,101,90,14,98,117,105,108,116,105, - 110,95,109,111,100,117,108,101,114,5,0,0,0,114,5,0, - 0,0,114,8,0,0,0,218,6,95,115,101,116,117,112,39, - 6,0,0,115,70,0,0,0,0,8,4,1,6,1,6,2, - 10,3,22,1,12,2,22,1,8,1,10,1,10,1,6,2, - 2,1,10,1,10,1,12,1,12,2,8,2,12,1,12,1, - 18,1,22,3,8,1,10,1,10,1,8,1,12,1,12,2, - 10,1,16,3,14,1,14,1,10,1,10,1,10,1,114,89, - 1,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,67,0,0,0,115,50,0,0, - 0,116,0,124,0,131,1,1,0,116,1,131,0,125,1,116, - 2,106,3,160,4,116,5,106,6,124,1,142,0,103,1,161, - 1,1,0,116,2,106,7,160,8,116,9,161,1,1,0,100, - 1,83,0,41,2,122,41,73,110,115,116,97,108,108,32,116, - 104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,109, - 112,111,114,116,32,99,111,109,112,111,110,101,110,116,115,46, - 78,41,10,114,89,1,0,0,114,184,0,0,0,114,1,0, - 0,0,114,51,1,0,0,114,167,0,0,0,114,61,1,0, - 0,114,77,1,0,0,218,9,109,101,116,97,95,112,97,116, - 104,114,186,0,0,0,114,45,1,0,0,41,2,114,88,1, - 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, - 97,100,101,114,115,114,5,0,0,0,114,5,0,0,0,114, - 8,0,0,0,218,8,95,105,110,115,116,97,108,108,96,6, - 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, - 91,1,0,0,41,1,114,60,0,0,0,41,1,78,41,3, - 78,78,78,41,2,114,73,0,0,0,114,73,0,0,0,41, - 1,84,41,1,78,41,1,78,41,63,114,127,0,0,0,114, - 13,0,0,0,90,37,95,67,65,83,69,95,73,78,83,69, - 78,83,73,84,73,86,69,95,80,76,65,84,70,79,82,77, - 83,95,66,89,84,69,83,95,75,69,89,114,12,0,0,0, - 114,14,0,0,0,114,21,0,0,0,114,27,0,0,0,114, - 29,0,0,0,114,38,0,0,0,114,47,0,0,0,114,49, - 0,0,0,114,53,0,0,0,114,54,0,0,0,114,56,0, - 0,0,114,59,0,0,0,114,69,0,0,0,218,4,116,121, - 112,101,218,8,95,95,99,111,100,101,95,95,114,162,0,0, - 0,114,19,0,0,0,114,148,0,0,0,114,18,0,0,0, - 114,24,0,0,0,114,236,0,0,0,114,91,0,0,0,114, - 87,0,0,0,114,101,0,0,0,114,88,0,0,0,90,23, - 68,69,66,85,71,95,66,89,84,69,67,79,68,69,95,83, - 85,70,70,73,88,69,83,90,27,79,80,84,73,77,73,90, - 69,68,95,66,89,84,69,67,79,68,69,95,83,85,70,70, - 73,88,69,83,114,97,0,0,0,114,102,0,0,0,114,108, - 0,0,0,114,112,0,0,0,114,114,0,0,0,114,136,0, - 0,0,114,143,0,0,0,114,152,0,0,0,114,156,0,0, - 0,114,158,0,0,0,114,165,0,0,0,114,170,0,0,0, - 114,171,0,0,0,114,176,0,0,0,218,6,111,98,106,101, - 99,116,114,185,0,0,0,114,190,0,0,0,114,191,0,0, - 0,114,208,0,0,0,114,221,0,0,0,114,239,0,0,0, - 114,9,1,0,0,114,15,1,0,0,114,21,1,0,0,114, - 252,0,0,0,114,22,1,0,0,114,43,1,0,0,114,45, - 1,0,0,114,61,1,0,0,114,82,1,0,0,114,184,0, - 0,0,114,89,1,0,0,114,91,1,0,0,114,5,0,0, - 0,114,5,0,0,0,114,5,0,0,0,114,8,0,0,0, - 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,126, - 0,0,0,4,22,4,1,4,1,2,1,2,255,4,4,8, - 17,8,5,8,5,8,6,8,6,8,12,8,10,8,9,8, - 5,8,7,8,9,10,22,10,127,0,20,16,1,12,2,4, - 1,4,2,6,2,6,2,8,2,16,71,8,40,8,19,8, - 12,8,12,8,28,8,17,8,33,8,28,8,24,10,13,10, - 10,10,11,8,14,6,3,4,1,2,255,12,68,14,64,14, - 29,16,127,0,17,14,72,18,45,18,26,4,3,18,53,14, - 63,14,42,14,127,0,20,14,127,0,22,10,23,8,11,8, - 57, + 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, + 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, + 4,83,0,41,1,114,74,0,0,0,114,5,0,0,0,41, + 2,114,32,0,0,0,218,1,115,114,5,0,0,0,114,5, + 0,0,0,114,8,0,0,0,114,64,1,0,0,52,6,0, + 0,114,56,1,0,0,122,25,95,115,101,116,117,112,46,60, + 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, + 62,41,3,114,64,0,0,0,114,75,0,0,0,114,160,0, + 0,0,114,192,0,0,0,114,9,0,0,0,122,4,46,112, + 121,119,122,6,95,100,46,112,121,100,84,78,41,18,114,134, + 0,0,0,114,1,0,0,0,114,163,0,0,0,114,22,1, + 0,0,114,125,0,0,0,218,3,97,108,108,90,18,95,98, + 117,105,108,116,105,110,95,102,114,111,109,95,110,97,109,101, + 114,117,0,0,0,114,129,0,0,0,114,36,0,0,0,114, + 186,0,0,0,114,14,0,0,0,114,12,1,0,0,114,167, + 0,0,0,114,76,1,0,0,114,101,0,0,0,114,191,0, + 0,0,114,195,0,0,0,41,10,218,17,95,98,111,111,116, + 115,116,114,97,112,95,109,111,100,117,108,101,90,11,115,101, + 108,102,95,109,111,100,117,108,101,90,10,111,115,95,100,101, + 116,97,105,108,115,90,10,98,117,105,108,116,105,110,95,111, + 115,114,31,0,0,0,114,35,0,0,0,90,9,111,115,95, + 109,111,100,117,108,101,90,13,98,117,105,108,116,105,110,95, + 110,97,109,101,115,90,12,98,117,105,108,116,105,110,95,110, + 97,109,101,90,14,98,117,105,108,116,105,110,95,109,111,100, + 117,108,101,114,5,0,0,0,114,5,0,0,0,114,8,0, + 0,0,218,6,95,115,101,116,117,112,17,6,0,0,115,70, + 0,0,0,0,8,4,1,6,1,6,2,10,3,22,1,12, + 2,22,1,8,1,10,1,10,1,6,2,2,1,10,1,10, + 1,12,1,12,2,8,2,12,1,12,1,18,1,22,3,8, + 1,10,1,10,1,8,1,12,1,12,2,10,1,16,3,14, + 1,14,1,10,1,10,1,10,1,114,82,1,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,67,0,0,0,115,50,0,0,0,116,0,124,0, + 131,1,1,0,116,1,131,0,125,1,116,2,106,3,160,4, + 116,5,106,6,124,1,142,0,103,1,161,1,1,0,116,2, + 106,7,160,8,116,9,161,1,1,0,100,1,83,0,41,2, + 122,41,73,110,115,116,97,108,108,32,116,104,101,32,112,97, + 116,104,45,98,97,115,101,100,32,105,109,112,111,114,116,32, + 99,111,109,112,111,110,101,110,116,115,46,78,41,10,114,82, + 1,0,0,114,184,0,0,0,114,1,0,0,0,114,43,1, + 0,0,114,167,0,0,0,114,54,1,0,0,114,70,1,0, + 0,218,9,109,101,116,97,95,112,97,116,104,114,186,0,0, + 0,114,37,1,0,0,41,2,114,81,1,0,0,90,17,115, + 117,112,112,111,114,116,101,100,95,108,111,97,100,101,114,115, + 114,5,0,0,0,114,5,0,0,0,114,8,0,0,0,218, + 8,95,105,110,115,116,97,108,108,74,6,0,0,115,8,0, + 0,0,0,2,8,1,6,1,20,1,114,84,1,0,0,41, + 1,114,60,0,0,0,41,1,78,41,3,78,78,78,41,2, + 114,73,0,0,0,114,73,0,0,0,41,1,84,41,1,78, + 41,1,78,41,63,114,127,0,0,0,114,13,0,0,0,90, + 37,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, + 86,69,95,80,76,65,84,70,79,82,77,83,95,66,89,84, + 69,83,95,75,69,89,114,12,0,0,0,114,14,0,0,0, + 114,21,0,0,0,114,27,0,0,0,114,29,0,0,0,114, + 38,0,0,0,114,47,0,0,0,114,49,0,0,0,114,53, + 0,0,0,114,54,0,0,0,114,56,0,0,0,114,59,0, + 0,0,114,69,0,0,0,218,4,116,121,112,101,218,8,95, + 95,99,111,100,101,95,95,114,162,0,0,0,114,19,0,0, + 0,114,148,0,0,0,114,18,0,0,0,114,24,0,0,0, + 114,236,0,0,0,114,91,0,0,0,114,87,0,0,0,114, + 101,0,0,0,114,88,0,0,0,90,23,68,69,66,85,71, + 95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, + 69,83,90,27,79,80,84,73,77,73,90,69,68,95,66,89, + 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,114, + 97,0,0,0,114,102,0,0,0,114,108,0,0,0,114,112, + 0,0,0,114,114,0,0,0,114,136,0,0,0,114,143,0, + 0,0,114,152,0,0,0,114,156,0,0,0,114,158,0,0, + 0,114,165,0,0,0,114,170,0,0,0,114,171,0,0,0, + 114,176,0,0,0,218,6,111,98,106,101,99,116,114,185,0, + 0,0,114,190,0,0,0,114,191,0,0,0,114,208,0,0, + 0,114,221,0,0,0,114,239,0,0,0,114,255,0,0,0, + 114,5,1,0,0,114,12,1,0,0,114,252,0,0,0,114, + 13,1,0,0,114,35,1,0,0,114,37,1,0,0,114,54, + 1,0,0,114,75,1,0,0,114,184,0,0,0,114,82,1, + 0,0,114,84,1,0,0,114,5,0,0,0,114,5,0,0, + 0,114,5,0,0,0,114,8,0,0,0,218,8,60,109,111, + 100,117,108,101,62,1,0,0,0,115,126,0,0,0,4,22, + 4,1,4,1,2,1,2,255,4,4,8,17,8,5,8,5, + 8,6,8,6,8,12,8,10,8,9,8,5,8,7,8,9, + 10,22,10,127,0,20,16,1,12,2,4,1,4,2,6,2, + 6,2,8,2,16,71,8,40,8,19,8,12,8,12,8,28, + 8,17,8,33,8,28,8,24,10,13,10,10,10,11,8,14, + 6,3,4,1,2,255,12,68,14,64,14,29,16,127,0,17, + 14,50,18,45,18,26,4,3,18,53,14,63,14,42,14,127, + 0,20,14,127,0,22,10,23,8,11,8,57, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index 373b1366bdea3..be7d24fe1df25 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -1,7 +1,7 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__zipimport[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,82,1,0,0,100,0, + 0,4,0,0,0,64,0,0,0,115,68,1,0,0,100,0, 90,0,100,1,100,2,108,1,90,2,100,1,100,3,108,1, 109,3,90,3,109,4,90,4,1,0,100,1,100,2,108,5, 90,6,100,1,100,2,108,7,90,7,100,1,100,2,108,8, @@ -21,1059 +21,941 @@ const unsigned char _Py_M__zipimport[] = { 132,0,90,35,101,19,101,35,106,36,131,1,90,37,100,35, 100,36,132,0,90,38,100,37,100,38,132,0,90,39,100,39, 100,40,132,0,90,40,100,41,100,42,132,0,90,41,100,43, - 100,44,132,0,90,42,100,45,100,46,132,0,90,43,71,0, - 100,47,100,48,132,0,100,48,131,2,90,44,100,2,83,0, - 41,49,97,80,2,0,0,122,105,112,105,109,112,111,114,116, - 32,112,114,111,118,105,100,101,115,32,115,117,112,112,111,114, - 116,32,102,111,114,32,105,109,112,111,114,116,105,110,103,32, - 80,121,116,104,111,110,32,109,111,100,117,108,101,115,32,102, - 114,111,109,32,90,105,112,32,97,114,99,104,105,118,101,115, - 46,10,10,84,104,105,115,32,109,111,100,117,108,101,32,101, - 120,112,111,114,116,115,32,116,104,114,101,101,32,111,98,106, - 101,99,116,115,58,10,45,32,122,105,112,105,109,112,111,114, - 116,101,114,58,32,97,32,99,108,97,115,115,59,32,105,116, - 115,32,99,111,110,115,116,114,117,99,116,111,114,32,116,97, - 107,101,115,32,97,32,112,97,116,104,32,116,111,32,97,32, - 90,105,112,32,97,114,99,104,105,118,101,46,10,45,32,90, - 105,112,73,109,112,111,114,116,69,114,114,111,114,58,32,101, - 120,99,101,112,116,105,111,110,32,114,97,105,115,101,100,32, - 98,121,32,122,105,112,105,109,112,111,114,116,101,114,32,111, - 98,106,101,99,116,115,46,32,73,116,39,115,32,97,10,32, - 32,115,117,98,99,108,97,115,115,32,111,102,32,73,109,112, - 111,114,116,69,114,114,111,114,44,32,115,111,32,105,116,32, - 99,97,110,32,98,101,32,99,97,117,103,104,116,32,97,115, - 32,73,109,112,111,114,116,69,114,114,111,114,44,32,116,111, - 111,46,10,45,32,95,122,105,112,95,100,105,114,101,99,116, - 111,114,121,95,99,97,99,104,101,58,32,97,32,100,105,99, - 116,44,32,109,97,112,112,105,110,103,32,97,114,99,104,105, - 118,101,32,112,97,116,104,115,32,116,111,32,122,105,112,32, - 100,105,114,101,99,116,111,114,121,10,32,32,105,110,102,111, - 32,100,105,99,116,115,44,32,97,115,32,117,115,101,100,32, - 105,110,32,122,105,112,105,109,112,111,114,116,101,114,46,95, - 102,105,108,101,115,46,10,10,73,116,32,105,115,32,117,115, - 117,97,108,108,121,32,110,111,116,32,110,101,101,100,101,100, - 32,116,111,32,117,115,101,32,116,104,101,32,122,105,112,105, - 109,112,111,114,116,32,109,111,100,117,108,101,32,101,120,112, - 108,105,99,105,116,108,121,59,32,105,116,32,105,115,10,117, - 115,101,100,32,98,121,32,116,104,101,32,98,117,105,108,116, - 105,110,32,105,109,112,111,114,116,32,109,101,99,104,97,110, - 105,115,109,32,102,111,114,32,115,121,115,46,112,97,116,104, - 32,105,116,101,109,115,32,116,104,97,116,32,97,114,101,32, - 112,97,116,104,115,10,116,111,32,90,105,112,32,97,114,99, - 104,105,118,101,115,46,10,233,0,0,0,0,78,41,2,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,49,54,218, - 14,95,117,110,112,97,99,107,95,117,105,110,116,51,50,218, - 14,90,105,112,73,109,112,111,114,116,69,114,114,111,114,218, - 11,122,105,112,105,109,112,111,114,116,101,114,233,1,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,64,0,0,0,115,12,0,0,0,101, - 0,90,1,100,0,90,2,100,1,83,0,41,2,114,3,0, - 0,0,78,41,3,218,8,95,95,110,97,109,101,95,95,218, - 10,95,95,109,111,100,117,108,101,95,95,218,12,95,95,113, - 117,97,108,110,97,109,101,95,95,169,0,114,9,0,0,0, - 114,9,0,0,0,250,18,60,102,114,111,122,101,110,32,122, - 105,112,105,109,112,111,114,116,62,114,3,0,0,0,33,0, - 0,0,115,2,0,0,0,8,1,233,22,0,0,0,115,4, - 0,0,0,80,75,5,6,105,255,255,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,64,0,0,0,115,108,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,100,3,132,0,90,4,100,25, - 100,5,100,6,132,1,90,5,100,26,100,7,100,8,132,1, - 90,6,100,9,100,10,132,0,90,7,100,11,100,12,132,0, - 90,8,100,13,100,14,132,0,90,9,100,15,100,16,132,0, - 90,10,100,17,100,18,132,0,90,11,100,19,100,20,132,0, - 90,12,100,21,100,22,132,0,90,13,100,23,100,24,132,0, - 90,14,100,4,83,0,41,27,114,4,0,0,0,97,255,1, - 0,0,122,105,112,105,109,112,111,114,116,101,114,40,97,114, - 99,104,105,118,101,112,97,116,104,41,32,45,62,32,122,105, - 112,105,109,112,111,114,116,101,114,32,111,98,106,101,99,116, - 10,10,32,32,32,32,67,114,101,97,116,101,32,97,32,110, - 101,119,32,122,105,112,105,109,112,111,114,116,101,114,32,105, - 110,115,116,97,110,99,101,46,32,39,97,114,99,104,105,118, - 101,112,97,116,104,39,32,109,117,115,116,32,98,101,32,97, - 32,112,97,116,104,32,116,111,10,32,32,32,32,97,32,122, - 105,112,102,105,108,101,44,32,111,114,32,116,111,32,97,32, - 115,112,101,99,105,102,105,99,32,112,97,116,104,32,105,110, - 115,105,100,101,32,97,32,122,105,112,102,105,108,101,46,32, - 70,111,114,32,101,120,97,109,112,108,101,44,32,105,116,32, - 99,97,110,32,98,101,10,32,32,32,32,39,47,116,109,112, - 47,109,121,105,109,112,111,114,116,46,122,105,112,39,44,32, - 111,114,32,39,47,116,109,112,47,109,121,105,109,112,111,114, - 116,46,122,105,112,47,109,121,100,105,114,101,99,116,111,114, - 121,39,44,32,105,102,32,109,121,100,105,114,101,99,116,111, - 114,121,32,105,115,32,97,10,32,32,32,32,118,97,108,105, - 100,32,100,105,114,101,99,116,111,114,121,32,105,110,115,105, - 100,101,32,116,104,101,32,97,114,99,104,105,118,101,46,10, - 10,32,32,32,32,39,90,105,112,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, - 102,32,39,97,114,99,104,105,118,101,112,97,116,104,39,32, - 100,111,101,115,110,39,116,32,112,111,105,110,116,32,116,111, - 32,97,32,118,97,108,105,100,32,90,105,112,10,32,32,32, - 32,97,114,99,104,105,118,101,46,10,10,32,32,32,32,84, - 104,101,32,39,97,114,99,104,105,118,101,39,32,97,116,116, - 114,105,98,117,116,101,32,111,102,32,122,105,112,105,109,112, - 111,114,116,101,114,32,111,98,106,101,99,116,115,32,99,111, - 110,116,97,105,110,115,32,116,104,101,32,110,97,109,101,32, - 111,102,32,116,104,101,10,32,32,32,32,122,105,112,102,105, - 108,101,32,116,97,114,103,101,116,101,100,46,10,32,32,32, - 32,99,2,0,0,0,0,0,0,0,0,0,0,0,8,0, - 0,0,9,0,0,0,67,0,0,0,115,32,1,0,0,116, - 0,124,1,116,1,131,2,115,28,100,1,100,0,108,2,125, - 2,124,2,160,3,124,1,161,1,125,1,124,1,115,44,116, - 4,100,2,124,1,100,3,141,2,130,1,116,5,114,60,124, - 1,160,6,116,5,116,7,161,2,125,1,103,0,125,3,122, - 14,116,8,160,9,124,1,161,1,125,4,87,0,110,70,4, - 0,116,10,116,11,102,2,121,148,1,0,1,0,1,0,116, - 8,160,12,124,1,161,1,92,2,125,5,125,6,124,5,124, - 1,107,2,114,130,116,4,100,4,124,1,100,3,141,2,130, - 1,124,5,125,1,124,3,160,13,124,6,161,1,1,0,89, - 0,113,64,48,0,124,4,106,14,100,5,64,0,100,6,107, - 3,114,180,116,4,100,4,124,1,100,3,141,2,130,1,113, - 180,113,64,122,12,116,15,124,1,25,0,125,7,87,0,110, - 34,4,0,116,16,121,226,1,0,1,0,1,0,116,17,124, - 1,131,1,125,7,124,7,116,15,124,1,60,0,89,0,110, - 2,48,0,124,7,124,0,95,18,124,1,124,0,95,19,116, - 8,106,20,124,3,100,0,100,0,100,7,133,3,25,0,142, - 0,124,0,95,21,124,0,106,21,144,1,114,28,124,0,4, - 0,106,21,116,7,55,0,2,0,95,21,100,0,83,0,41, - 8,78,114,0,0,0,0,122,21,97,114,99,104,105,118,101, - 32,112,97,116,104,32,105,115,32,101,109,112,116,121,169,1, - 218,4,112,97,116,104,122,14,110,111,116,32,97,32,90,105, - 112,32,102,105,108,101,105,0,240,0,0,105,0,128,0,0, - 233,255,255,255,255,41,22,218,10,105,115,105,110,115,116,97, - 110,99,101,218,3,115,116,114,218,2,111,115,90,8,102,115, - 100,101,99,111,100,101,114,3,0,0,0,218,12,97,108,116, - 95,112,97,116,104,95,115,101,112,218,7,114,101,112,108,97, - 99,101,218,8,112,97,116,104,95,115,101,112,218,19,95,98, - 111,111,116,115,116,114,97,112,95,101,120,116,101,114,110,97, - 108,90,10,95,112,97,116,104,95,115,116,97,116,218,7,79, - 83,69,114,114,111,114,218,10,86,97,108,117,101,69,114,114, - 111,114,90,11,95,112,97,116,104,95,115,112,108,105,116,218, - 6,97,112,112,101,110,100,90,7,115,116,95,109,111,100,101, - 218,20,95,122,105,112,95,100,105,114,101,99,116,111,114,121, - 95,99,97,99,104,101,218,8,75,101,121,69,114,114,111,114, - 218,15,95,114,101,97,100,95,100,105,114,101,99,116,111,114, - 121,218,6,95,102,105,108,101,115,218,7,97,114,99,104,105, - 118,101,218,10,95,112,97,116,104,95,106,111,105,110,218,6, - 112,114,101,102,105,120,41,8,218,4,115,101,108,102,114,13, - 0,0,0,114,17,0,0,0,114,31,0,0,0,90,2,115, - 116,90,7,100,105,114,110,97,109,101,90,8,98,97,115,101, - 110,97,109,101,218,5,102,105,108,101,115,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,8,95,95,105,110, - 105,116,95,95,63,0,0,0,115,58,0,0,0,0,1,10, - 1,8,1,10,1,4,1,12,1,4,1,12,2,4,2,2, - 1,14,1,16,3,14,1,8,1,12,1,4,1,16,3,14, - 2,12,1,4,2,2,1,12,1,12,1,8,1,14,1,6, - 1,6,2,22,1,8,1,122,20,122,105,112,105,109,112,111, - 114,116,101,114,46,95,95,105,110,105,116,95,95,78,99,3, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4, - 0,0,0,67,0,0,0,115,78,0,0,0,116,0,124,0, - 124,1,131,2,125,3,124,3,100,1,117,1,114,26,124,0, - 103,0,102,2,83,0,116,1,124,0,124,1,131,2,125,4, - 116,2,124,0,124,4,131,2,114,70,100,1,124,0,106,3, - 155,0,116,4,155,0,124,4,155,0,157,3,103,1,102,2, - 83,0,100,1,103,0,102,2,83,0,41,2,97,239,1,0, - 0,102,105,110,100,95,108,111,97,100,101,114,40,102,117,108, - 108,110,97,109,101,44,32,112,97,116,104,61,78,111,110,101, - 41,32,45,62,32,115,101,108,102,44,32,115,116,114,32,111, - 114,32,78,111,110,101,46,10,10,32,32,32,32,32,32,32, - 32,83,101,97,114,99,104,32,102,111,114,32,97,32,109,111, - 100,117,108,101,32,115,112,101,99,105,102,105,101,100,32,98, - 121,32,39,102,117,108,108,110,97,109,101,39,46,32,39,102, - 117,108,108,110,97,109,101,39,32,109,117,115,116,32,98,101, - 32,116,104,101,10,32,32,32,32,32,32,32,32,102,117,108, - 108,121,32,113,117,97,108,105,102,105,101,100,32,40,100,111, - 116,116,101,100,41,32,109,111,100,117,108,101,32,110,97,109, - 101,46,32,73,116,32,114,101,116,117,114,110,115,32,116,104, - 101,32,122,105,112,105,109,112,111,114,116,101,114,10,32,32, - 32,32,32,32,32,32,105,110,115,116,97,110,99,101,32,105, - 116,115,101,108,102,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,119,97,115,32,102,111,117,110,100,44,32,97, - 32,115,116,114,105,110,103,32,99,111,110,116,97,105,110,105, - 110,103,32,116,104,101,10,32,32,32,32,32,32,32,32,102, - 117,108,108,32,112,97,116,104,32,110,97,109,101,32,105,102, - 32,105,116,39,115,32,112,111,115,115,105,98,108,121,32,97, - 32,112,111,114,116,105,111,110,32,111,102,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,44, - 10,32,32,32,32,32,32,32,32,111,114,32,78,111,110,101, - 32,111,116,104,101,114,119,105,115,101,46,32,84,104,101,32, - 111,112,116,105,111,110,97,108,32,39,112,97,116,104,39,32, - 97,114,103,117,109,101,110,116,32,105,115,32,105,103,110,111, - 114,101,100,32,45,45,32,105,116,39,115,10,32,32,32,32, - 32,32,32,32,116,104,101,114,101,32,102,111,114,32,99,111, - 109,112,97,116,105,98,105,108,105,116,121,32,119,105,116,104, - 32,116,104,101,32,105,109,112,111,114,116,101,114,32,112,114, - 111,116,111,99,111,108,46,10,32,32,32,32,32,32,32,32, - 78,41,5,218,16,95,103,101,116,95,109,111,100,117,108,101, - 95,105,110,102,111,218,16,95,103,101,116,95,109,111,100,117, - 108,101,95,112,97,116,104,218,7,95,105,115,95,100,105,114, - 114,29,0,0,0,114,20,0,0,0,41,5,114,32,0,0, - 0,218,8,102,117,108,108,110,97,109,101,114,13,0,0,0, - 218,2,109,105,218,7,109,111,100,112,97,116,104,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,11,102,105, - 110,100,95,108,111,97,100,101,114,109,0,0,0,115,14,0, - 0,0,0,10,10,1,8,2,8,7,10,1,10,4,24,2, - 122,23,122,105,112,105,109,112,111,114,116,101,114,46,102,105, - 110,100,95,108,111,97,100,101,114,99,3,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, - 0,0,115,16,0,0,0,124,0,160,0,124,1,124,2,161, - 2,100,1,25,0,83,0,41,2,97,139,1,0,0,102,105, - 110,100,95,109,111,100,117,108,101,40,102,117,108,108,110,97, - 109,101,44,32,112,97,116,104,61,78,111,110,101,41,32,45, - 62,32,115,101,108,102,32,111,114,32,78,111,110,101,46,10, - 10,32,32,32,32,32,32,32,32,83,101,97,114,99,104,32, - 102,111,114,32,97,32,109,111,100,117,108,101,32,115,112,101, - 99,105,102,105,101,100,32,98,121,32,39,102,117,108,108,110, - 97,109,101,39,46,32,39,102,117,108,108,110,97,109,101,39, - 32,109,117,115,116,32,98,101,32,116,104,101,10,32,32,32, - 32,32,32,32,32,102,117,108,108,121,32,113,117,97,108,105, - 102,105,101,100,32,40,100,111,116,116,101,100,41,32,109,111, - 100,117,108,101,32,110,97,109,101,46,32,73,116,32,114,101, - 116,117,114,110,115,32,116,104,101,32,122,105,112,105,109,112, - 111,114,116,101,114,10,32,32,32,32,32,32,32,32,105,110, - 115,116,97,110,99,101,32,105,116,115,101,108,102,32,105,102, - 32,116,104,101,32,109,111,100,117,108,101,32,119,97,115,32, - 102,111,117,110,100,44,32,111,114,32,78,111,110,101,32,105, - 102,32,105,116,32,119,97,115,110,39,116,46,10,32,32,32, - 32,32,32,32,32,84,104,101,32,111,112,116,105,111,110,97, - 108,32,39,112,97,116,104,39,32,97,114,103,117,109,101,110, - 116,32,105,115,32,105,103,110,111,114,101,100,32,45,45,32, - 105,116,39,115,32,116,104,101,114,101,32,102,111,114,32,99, - 111,109,112,97,116,105,98,105,108,105,116,121,10,32,32,32, - 32,32,32,32,32,119,105,116,104,32,116,104,101,32,105,109, - 112,111,114,116,101,114,32,112,114,111,116,111,99,111,108,46, - 10,32,32,32,32,32,32,32,32,114,0,0,0,0,41,1, - 114,41,0,0,0,41,3,114,32,0,0,0,114,38,0,0, - 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,11,102,105,110,100,95,109,111,100,117, - 108,101,141,0,0,0,115,2,0,0,0,0,9,122,23,122, - 105,112,105,109,112,111,114,116,101,114,46,102,105,110,100,95, - 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,115, - 20,0,0,0,116,0,124,0,124,1,131,2,92,3,125,2, - 125,3,125,4,124,2,83,0,41,1,122,163,103,101,116,95, - 99,111,100,101,40,102,117,108,108,110,97,109,101,41,32,45, - 62,32,99,111,100,101,32,111,98,106,101,99,116,46,10,10, - 32,32,32,32,32,32,32,32,82,101,116,117,114,110,32,116, - 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,46,32,82,97,105,115,101,32,90, - 105,112,73,109,112,111,114,116,69,114,114,111,114,10,32,32, - 32,32,32,32,32,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,99,111,117,108,100,110,39,116,32,98,101,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,169, - 1,218,16,95,103,101,116,95,109,111,100,117,108,101,95,99, - 111,100,101,169,5,114,32,0,0,0,114,38,0,0,0,218, - 4,99,111,100,101,218,9,105,115,112,97,99,107,97,103,101, - 114,40,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,8,103,101,116,95,99,111,100,101,153,0, - 0,0,115,4,0,0,0,0,6,16,1,122,20,122,105,112, - 105,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,8,0,0,0,67,0,0,0,115,116,0,0,0,116, - 0,114,16,124,1,160,1,116,0,116,2,161,2,125,1,124, - 1,125,2,124,1,160,3,124,0,106,4,116,2,23,0,161, - 1,114,58,124,1,116,5,124,0,106,4,116,2,23,0,131, - 1,100,1,133,2,25,0,125,2,122,14,124,0,106,6,124, - 2,25,0,125,3,87,0,110,30,4,0,116,7,121,102,1, - 0,1,0,1,0,116,8,100,2,100,3,124,2,131,3,130, - 1,89,0,110,2,48,0,116,9,124,0,106,4,124,3,131, - 2,83,0,41,4,122,154,103,101,116,95,100,97,116,97,40, - 112,97,116,104,110,97,109,101,41,32,45,62,32,115,116,114, - 105,110,103,32,119,105,116,104,32,102,105,108,101,32,100,97, - 116,97,46,10,10,32,32,32,32,32,32,32,32,82,101,116, - 117,114,110,32,116,104,101,32,100,97,116,97,32,97,115,115, - 111,99,105,97,116,101,100,32,119,105,116,104,32,39,112,97, - 116,104,110,97,109,101,39,46,32,82,97,105,115,101,32,79, - 83,69,114,114,111,114,32,105,102,10,32,32,32,32,32,32, - 32,32,116,104,101,32,102,105,108,101,32,119,97,115,110,39, - 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, - 32,78,114,0,0,0,0,218,0,41,10,114,18,0,0,0, - 114,19,0,0,0,114,20,0,0,0,218,10,115,116,97,114, - 116,115,119,105,116,104,114,29,0,0,0,218,3,108,101,110, - 114,28,0,0,0,114,26,0,0,0,114,22,0,0,0,218, - 9,95,103,101,116,95,100,97,116,97,41,4,114,32,0,0, - 0,218,8,112,97,116,104,110,97,109,101,90,3,107,101,121, - 218,9,116,111,99,95,101,110,116,114,121,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,8,103,101,116,95, - 100,97,116,97,163,0,0,0,115,20,0,0,0,0,6,4, - 1,12,2,4,1,16,1,22,2,2,1,14,1,12,1,18, - 1,122,20,122,105,112,105,109,112,111,114,116,101,114,46,103, - 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,3,0,0,0,67,0,0,0, - 115,20,0,0,0,116,0,124,0,124,1,131,2,92,3,125, - 2,125,3,125,4,124,4,83,0,41,1,122,106,103,101,116, - 95,102,105,108,101,110,97,109,101,40,102,117,108,108,110,97, - 109,101,41,32,45,62,32,102,105,108,101,110,97,109,101,32, - 115,116,114,105,110,103,46,10,10,32,32,32,32,32,32,32, - 32,82,101,116,117,114,110,32,116,104,101,32,102,105,108,101, - 110,97,109,101,32,102,111,114,32,116,104,101,32,115,112,101, - 99,105,102,105,101,100,32,109,111,100,117,108,101,46,10,32, - 32,32,32,32,32,32,32,114,43,0,0,0,114,45,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,12,103,101,116,95,102,105,108,101,110,97,109,101,184,0, - 0,0,115,4,0,0,0,0,7,16,1,122,24,122,105,112, - 105,109,112,111,114,116,101,114,46,103,101,116,95,102,105,108, - 101,110,97,109,101,99,2,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,8,0,0,0,67,0,0,0,115,126, - 0,0,0,116,0,124,0,124,1,131,2,125,2,124,2,100, - 1,117,0,114,36,116,1,100,2,124,1,155,2,157,2,124, - 1,100,3,141,2,130,1,116,2,124,0,124,1,131,2,125, - 3,124,2,114,64,116,3,160,4,124,3,100,4,161,2,125, - 4,110,10,124,3,155,0,100,5,157,2,125,4,122,14,124, - 0,106,5,124,4,25,0,125,5,87,0,110,20,4,0,116, - 6,121,108,1,0,1,0,1,0,89,0,100,1,83,0,48, - 0,116,7,124,0,106,8,124,5,131,2,160,9,161,0,83, - 0,41,6,122,253,103,101,116,95,115,111,117,114,99,101,40, - 102,117,108,108,110,97,109,101,41,32,45,62,32,115,111,117, - 114,99,101,32,115,116,114,105,110,103,46,10,10,32,32,32, - 32,32,32,32,32,82,101,116,117,114,110,32,116,104,101,32, - 115,111,117,114,99,101,32,99,111,100,101,32,102,111,114,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,46,32,82,97,105,115,101,32,90,105,112,73, - 109,112,111,114,116,69,114,114,111,114,10,32,32,32,32,32, - 32,32,32,105,102,32,116,104,101,32,109,111,100,117,108,101, - 32,99,111,117,108,100,110,39,116,32,98,101,32,102,111,117, - 110,100,44,32,114,101,116,117,114,110,32,78,111,110,101,32, - 105,102,32,116,104,101,32,97,114,99,104,105,118,101,32,100, - 111,101,115,10,32,32,32,32,32,32,32,32,99,111,110,116, - 97,105,110,32,116,104,101,32,109,111,100,117,108,101,44,32, - 98,117,116,32,104,97,115,32,110,111,32,115,111,117,114,99, - 101,32,102,111,114,32,105,116,46,10,32,32,32,32,32,32, - 32,32,78,250,18,99,97,110,39,116,32,102,105,110,100,32, - 109,111,100,117,108,101,32,169,1,218,4,110,97,109,101,250, - 11,95,95,105,110,105,116,95,95,46,112,121,250,3,46,112, - 121,41,10,114,35,0,0,0,114,3,0,0,0,114,36,0, - 0,0,114,21,0,0,0,114,30,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, - 218,6,100,101,99,111,100,101,41,6,114,32,0,0,0,114, - 38,0,0,0,114,39,0,0,0,114,13,0,0,0,218,8, - 102,117,108,108,112,97,116,104,114,54,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,10,103,101, - 116,95,115,111,117,114,99,101,195,0,0,0,115,24,0,0, - 0,0,7,10,1,8,1,18,2,10,1,4,1,14,2,10, - 2,2,1,14,1,12,2,8,1,122,22,122,105,112,105,109, - 112,111,114,116,101,114,46,103,101,116,95,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,4,0,0,0,67,0,0,0,115,40,0,0,0,116, - 0,124,0,124,1,131,2,125,2,124,2,100,1,117,0,114, - 36,116,1,100,2,124,1,155,2,157,2,124,1,100,3,141, - 2,130,1,124,2,83,0,41,4,122,171,105,115,95,112,97, - 99,107,97,103,101,40,102,117,108,108,110,97,109,101,41,32, - 45,62,32,98,111,111,108,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,32,84,114,117,101,32,105,102, - 32,116,104,101,32,109,111,100,117,108,101,32,115,112,101,99, - 105,102,105,101,100,32,98,121,32,102,117,108,108,110,97,109, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,10, - 32,32,32,32,32,32,32,32,82,97,105,115,101,32,90,105, - 112,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, - 116,104,101,32,109,111,100,117,108,101,32,99,111,117,108,100, - 110,39,116,32,98,101,32,102,111,117,110,100,46,10,32,32, - 32,32,32,32,32,32,78,114,57,0,0,0,114,58,0,0, - 0,41,2,114,35,0,0,0,114,3,0,0,0,41,3,114, - 32,0,0,0,114,38,0,0,0,114,39,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,10,105, - 115,95,112,97,99,107,97,103,101,221,0,0,0,115,8,0, - 0,0,0,6,10,1,8,1,18,1,122,22,122,105,112,105, - 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97, - 103,101,99,2,0,0,0,0,0,0,0,0,0,0,0,8, - 0,0,0,8,0,0,0,67,0,0,0,115,246,0,0,0, - 116,0,124,0,124,1,131,2,92,3,125,2,125,3,125,4, - 116,1,106,2,160,3,124,1,161,1,125,5,124,5,100,1, - 117,0,115,46,116,4,124,5,116,5,131,2,115,64,116,5, - 124,1,131,1,125,5,124,5,116,1,106,2,124,1,60,0, - 124,0,124,5,95,6,122,84,124,3,114,108,116,7,124,0, - 124,1,131,2,125,6,116,8,160,9,124,0,106,10,124,6, - 161,2,125,7,124,7,103,1,124,5,95,11,116,12,124,5, - 100,2,131,2,115,124,116,13,124,5,95,13,116,8,160,14, - 124,5,106,15,124,1,124,4,161,3,1,0,116,16,124,2, - 124,5,106,15,131,2,1,0,87,0,110,22,1,0,1,0, - 1,0,116,1,106,2,124,1,61,0,130,0,89,0,110,2, - 48,0,122,14,116,1,106,2,124,1,25,0,125,5,87,0, - 110,34,4,0,116,17,121,226,1,0,1,0,1,0,116,18, - 100,3,124,1,155,2,100,4,157,3,131,1,130,1,89,0, - 110,2,48,0,116,19,160,20,100,5,124,1,124,4,161,3, - 1,0,124,5,83,0,41,6,122,245,108,111,97,100,95,109, - 111,100,117,108,101,40,102,117,108,108,110,97,109,101,41,32, - 45,62,32,109,111,100,117,108,101,46,10,10,32,32,32,32, - 32,32,32,32,76,111,97,100,32,116,104,101,32,109,111,100, - 117,108,101,32,115,112,101,99,105,102,105,101,100,32,98,121, - 32,39,102,117,108,108,110,97,109,101,39,46,32,39,102,117, - 108,108,110,97,109,101,39,32,109,117,115,116,32,98,101,32, - 116,104,101,10,32,32,32,32,32,32,32,32,102,117,108,108, - 121,32,113,117,97,108,105,102,105,101,100,32,40,100,111,116, - 116,101,100,41,32,109,111,100,117,108,101,32,110,97,109,101, - 46,32,73,116,32,114,101,116,117,114,110,115,32,116,104,101, - 32,105,109,112,111,114,116,101,100,10,32,32,32,32,32,32, - 32,32,109,111,100,117,108,101,44,32,111,114,32,114,97,105, - 115,101,115,32,90,105,112,73,109,112,111,114,116,69,114,114, - 111,114,32,105,102,32,105,116,32,119,97,115,110,39,116,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,78, - 218,12,95,95,98,117,105,108,116,105,110,115,95,95,122,14, - 76,111,97,100,101,100,32,109,111,100,117,108,101,32,122,25, - 32,110,111,116,32,102,111,117,110,100,32,105,110,32,115,121, - 115,46,109,111,100,117,108,101,115,122,30,105,109,112,111,114, - 116,32,123,125,32,35,32,108,111,97,100,101,100,32,102,114, - 111,109,32,90,105,112,32,123,125,41,21,114,44,0,0,0, - 218,3,115,121,115,218,7,109,111,100,117,108,101,115,218,3, - 103,101,116,114,15,0,0,0,218,12,95,109,111,100,117,108, - 101,95,116,121,112,101,218,10,95,95,108,111,97,100,101,114, - 95,95,114,36,0,0,0,114,21,0,0,0,114,30,0,0, - 0,114,29,0,0,0,90,8,95,95,112,97,116,104,95,95, - 218,7,104,97,115,97,116,116,114,114,66,0,0,0,90,14, - 95,102,105,120,95,117,112,95,109,111,100,117,108,101,218,8, - 95,95,100,105,99,116,95,95,218,4,101,120,101,99,114,26, - 0,0,0,218,11,73,109,112,111,114,116,69,114,114,111,114, - 218,10,95,98,111,111,116,115,116,114,97,112,218,16,95,118, - 101,114,98,111,115,101,95,109,101,115,115,97,103,101,41,8, - 114,32,0,0,0,114,38,0,0,0,114,46,0,0,0,114, - 47,0,0,0,114,40,0,0,0,90,3,109,111,100,114,13, - 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,234,0,0,0,115,48,0,0,0,0,7,16, - 1,12,1,18,1,8,1,10,1,6,2,2,1,4,3,10, - 1,14,1,8,2,10,1,6,1,16,1,16,1,6,1,8, - 1,8,2,2,1,14,1,12,1,22,1,14,1,122,23,122, - 105,112,105,109,112,111,114,116,101,114,46,108,111,97,100,95, - 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,8,0,0,0,67,0,0,0,115, - 86,0,0,0,122,20,124,0,160,0,124,1,161,1,115,18, - 87,0,100,1,83,0,87,0,110,20,4,0,116,1,121,40, - 1,0,1,0,1,0,89,0,100,1,83,0,48,0,116,2, - 106,3,115,76,100,2,100,3,108,4,109,5,125,2,1,0, - 124,2,160,6,116,2,161,1,1,0,100,4,116,2,95,3, - 116,2,124,0,124,1,131,2,83,0,41,5,122,204,82,101, - 116,117,114,110,32,116,104,101,32,82,101,115,111,117,114,99, - 101,82,101,97,100,101,114,32,102,111,114,32,97,32,112,97, - 99,107,97,103,101,32,105,110,32,97,32,122,105,112,32,102, - 105,108,101,46,10,10,32,32,32,32,32,32,32,32,73,102, - 32,39,102,117,108,108,110,97,109,101,39,32,105,115,32,97, - 32,112,97,99,107,97,103,101,32,119,105,116,104,105,110,32, - 116,104,101,32,122,105,112,32,102,105,108,101,44,32,114,101, - 116,117,114,110,32,116,104,101,10,32,32,32,32,32,32,32, - 32,39,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 39,32,111,98,106,101,99,116,32,102,111,114,32,116,104,101, - 32,112,97,99,107,97,103,101,46,32,32,79,116,104,101,114, - 119,105,115,101,32,114,101,116,117,114,110,32,78,111,110,101, - 46,10,32,32,32,32,32,32,32,32,78,114,0,0,0,0, - 41,1,218,14,82,101,115,111,117,114,99,101,82,101,97,100, - 101,114,84,41,7,114,65,0,0,0,114,3,0,0,0,218, - 24,95,90,105,112,73,109,112,111,114,116,82,101,115,111,117, - 114,99,101,82,101,97,100,101,114,218,11,95,114,101,103,105, - 115,116,101,114,101,100,90,13,105,109,112,111,114,116,108,105, - 98,46,97,98,99,114,79,0,0,0,90,8,114,101,103,105, - 115,116,101,114,41,3,114,32,0,0,0,114,38,0,0,0, - 114,79,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,19,103,101,116,95,114,101,115,111,117,114, - 99,101,95,114,101,97,100,101,114,16,1,0,0,115,20,0, - 0,0,0,6,2,1,10,1,10,1,12,1,8,1,6,1, - 12,1,10,1,6,1,122,31,122,105,112,105,109,112,111,114, - 116,101,114,46,103,101,116,95,114,101,115,111,117,114,99,101, - 95,114,101,97,100,101,114,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,5,0,0,0,67,0,0,0, - 115,24,0,0,0,100,1,124,0,106,0,155,0,116,1,155, - 0,124,0,106,2,155,0,100,2,157,5,83,0,41,3,78, - 122,21,60,122,105,112,105,109,112,111,114,116,101,114,32,111, - 98,106,101,99,116,32,34,122,2,34,62,41,3,114,29,0, - 0,0,114,20,0,0,0,114,31,0,0,0,41,1,114,32, + 100,44,132,0,90,42,100,45,100,46,132,0,90,43,100,2, + 83,0,41,47,97,80,2,0,0,122,105,112,105,109,112,111, + 114,116,32,112,114,111,118,105,100,101,115,32,115,117,112,112, + 111,114,116,32,102,111,114,32,105,109,112,111,114,116,105,110, + 103,32,80,121,116,104,111,110,32,109,111,100,117,108,101,115, + 32,102,114,111,109,32,90,105,112,32,97,114,99,104,105,118, + 101,115,46,10,10,84,104,105,115,32,109,111,100,117,108,101, + 32,101,120,112,111,114,116,115,32,116,104,114,101,101,32,111, + 98,106,101,99,116,115,58,10,45,32,122,105,112,105,109,112, + 111,114,116,101,114,58,32,97,32,99,108,97,115,115,59,32, + 105,116,115,32,99,111,110,115,116,114,117,99,116,111,114,32, + 116,97,107,101,115,32,97,32,112,97,116,104,32,116,111,32, + 97,32,90,105,112,32,97,114,99,104,105,118,101,46,10,45, + 32,90,105,112,73,109,112,111,114,116,69,114,114,111,114,58, + 32,101,120,99,101,112,116,105,111,110,32,114,97,105,115,101, + 100,32,98,121,32,122,105,112,105,109,112,111,114,116,101,114, + 32,111,98,106,101,99,116,115,46,32,73,116,39,115,32,97, + 10,32,32,115,117,98,99,108,97,115,115,32,111,102,32,73, + 109,112,111,114,116,69,114,114,111,114,44,32,115,111,32,105, + 116,32,99,97,110,32,98,101,32,99,97,117,103,104,116,32, + 97,115,32,73,109,112,111,114,116,69,114,114,111,114,44,32, + 116,111,111,46,10,45,32,95,122,105,112,95,100,105,114,101, + 99,116,111,114,121,95,99,97,99,104,101,58,32,97,32,100, + 105,99,116,44,32,109,97,112,112,105,110,103,32,97,114,99, + 104,105,118,101,32,112,97,116,104,115,32,116,111,32,122,105, + 112,32,100,105,114,101,99,116,111,114,121,10,32,32,105,110, + 102,111,32,100,105,99,116,115,44,32,97,115,32,117,115,101, + 100,32,105,110,32,122,105,112,105,109,112,111,114,116,101,114, + 46,95,102,105,108,101,115,46,10,10,73,116,32,105,115,32, + 117,115,117,97,108,108,121,32,110,111,116,32,110,101,101,100, + 101,100,32,116,111,32,117,115,101,32,116,104,101,32,122,105, + 112,105,109,112,111,114,116,32,109,111,100,117,108,101,32,101, + 120,112,108,105,99,105,116,108,121,59,32,105,116,32,105,115, + 10,117,115,101,100,32,98,121,32,116,104,101,32,98,117,105, + 108,116,105,110,32,105,109,112,111,114,116,32,109,101,99,104, + 97,110,105,115,109,32,102,111,114,32,115,121,115,46,112,97, + 116,104,32,105,116,101,109,115,32,116,104,97,116,32,97,114, + 101,32,112,97,116,104,115,10,116,111,32,90,105,112,32,97, + 114,99,104,105,118,101,115,46,10,233,0,0,0,0,78,41, + 2,218,14,95,117,110,112,97,99,107,95,117,105,110,116,49, + 54,218,14,95,117,110,112,97,99,107,95,117,105,110,116,51, + 50,218,14,90,105,112,73,109,112,111,114,116,69,114,114,111, + 114,218,11,122,105,112,105,109,112,111,114,116,101,114,233,1, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,64,0,0,0,115,12,0,0, + 0,101,0,90,1,100,0,90,2,100,1,83,0,41,2,114, + 3,0,0,0,78,41,3,218,8,95,95,110,97,109,101,95, + 95,218,10,95,95,109,111,100,117,108,101,95,95,218,12,95, + 95,113,117,97,108,110,97,109,101,95,95,169,0,114,9,0, + 0,0,114,9,0,0,0,250,18,60,102,114,111,122,101,110, + 32,122,105,112,105,109,112,111,114,116,62,114,3,0,0,0, + 33,0,0,0,115,2,0,0,0,8,1,233,22,0,0,0, + 115,4,0,0,0,80,75,5,6,105,255,255,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,64,0,0,0,115,108,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,100,3,132,0,90,4, + 100,25,100,5,100,6,132,1,90,5,100,26,100,7,100,8, + 132,1,90,6,100,9,100,10,132,0,90,7,100,11,100,12, + 132,0,90,8,100,13,100,14,132,0,90,9,100,15,100,16, + 132,0,90,10,100,17,100,18,132,0,90,11,100,19,100,20, + 132,0,90,12,100,21,100,22,132,0,90,13,100,23,100,24, + 132,0,90,14,100,4,83,0,41,27,114,4,0,0,0,97, + 255,1,0,0,122,105,112,105,109,112,111,114,116,101,114,40, + 97,114,99,104,105,118,101,112,97,116,104,41,32,45,62,32, + 122,105,112,105,109,112,111,114,116,101,114,32,111,98,106,101, + 99,116,10,10,32,32,32,32,67,114,101,97,116,101,32,97, + 32,110,101,119,32,122,105,112,105,109,112,111,114,116,101,114, + 32,105,110,115,116,97,110,99,101,46,32,39,97,114,99,104, + 105,118,101,112,97,116,104,39,32,109,117,115,116,32,98,101, + 32,97,32,112,97,116,104,32,116,111,10,32,32,32,32,97, + 32,122,105,112,102,105,108,101,44,32,111,114,32,116,111,32, + 97,32,115,112,101,99,105,102,105,99,32,112,97,116,104,32, + 105,110,115,105,100,101,32,97,32,122,105,112,102,105,108,101, + 46,32,70,111,114,32,101,120,97,109,112,108,101,44,32,105, + 116,32,99,97,110,32,98,101,10,32,32,32,32,39,47,116, + 109,112,47,109,121,105,109,112,111,114,116,46,122,105,112,39, + 44,32,111,114,32,39,47,116,109,112,47,109,121,105,109,112, + 111,114,116,46,122,105,112,47,109,121,100,105,114,101,99,116, + 111,114,121,39,44,32,105,102,32,109,121,100,105,114,101,99, + 116,111,114,121,32,105,115,32,97,10,32,32,32,32,118,97, + 108,105,100,32,100,105,114,101,99,116,111,114,121,32,105,110, + 115,105,100,101,32,116,104,101,32,97,114,99,104,105,118,101, + 46,10,10,32,32,32,32,39,90,105,112,73,109,112,111,114, + 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 32,105,102,32,39,97,114,99,104,105,118,101,112,97,116,104, + 39,32,100,111,101,115,110,39,116,32,112,111,105,110,116,32, + 116,111,32,97,32,118,97,108,105,100,32,90,105,112,10,32, + 32,32,32,97,114,99,104,105,118,101,46,10,10,32,32,32, + 32,84,104,101,32,39,97,114,99,104,105,118,101,39,32,97, + 116,116,114,105,98,117,116,101,32,111,102,32,122,105,112,105, + 109,112,111,114,116,101,114,32,111,98,106,101,99,116,115,32, + 99,111,110,116,97,105,110,115,32,116,104,101,32,110,97,109, + 101,32,111,102,32,116,104,101,10,32,32,32,32,122,105,112, + 102,105,108,101,32,116,97,114,103,101,116,101,100,46,10,32, + 32,32,32,99,2,0,0,0,0,0,0,0,0,0,0,0, + 8,0,0,0,9,0,0,0,67,0,0,0,115,32,1,0, + 0,116,0,124,1,116,1,131,2,115,28,100,1,100,0,108, + 2,125,2,124,2,160,3,124,1,161,1,125,1,124,1,115, + 44,116,4,100,2,124,1,100,3,141,2,130,1,116,5,114, + 60,124,1,160,6,116,5,116,7,161,2,125,1,103,0,125, + 3,122,14,116,8,160,9,124,1,161,1,125,4,87,0,110, + 70,4,0,116,10,116,11,102,2,121,148,1,0,1,0,1, + 0,116,8,160,12,124,1,161,1,92,2,125,5,125,6,124, + 5,124,1,107,2,114,130,116,4,100,4,124,1,100,3,141, + 2,130,1,124,5,125,1,124,3,160,13,124,6,161,1,1, + 0,89,0,113,64,48,0,124,4,106,14,100,5,64,0,100, + 6,107,3,114,180,116,4,100,4,124,1,100,3,141,2,130, + 1,113,180,113,64,122,12,116,15,124,1,25,0,125,7,87, + 0,110,34,4,0,116,16,121,226,1,0,1,0,1,0,116, + 17,124,1,131,1,125,7,124,7,116,15,124,1,60,0,89, + 0,110,2,48,0,124,7,124,0,95,18,124,1,124,0,95, + 19,116,8,106,20,124,3,100,0,100,0,100,7,133,3,25, + 0,142,0,124,0,95,21,124,0,106,21,144,1,114,28,124, + 0,4,0,106,21,116,7,55,0,2,0,95,21,100,0,83, + 0,41,8,78,114,0,0,0,0,122,21,97,114,99,104,105, + 118,101,32,112,97,116,104,32,105,115,32,101,109,112,116,121, + 169,1,218,4,112,97,116,104,122,14,110,111,116,32,97,32, + 90,105,112,32,102,105,108,101,105,0,240,0,0,105,0,128, + 0,0,233,255,255,255,255,41,22,218,10,105,115,105,110,115, + 116,97,110,99,101,218,3,115,116,114,218,2,111,115,90,8, + 102,115,100,101,99,111,100,101,114,3,0,0,0,218,12,97, + 108,116,95,112,97,116,104,95,115,101,112,218,7,114,101,112, + 108,97,99,101,218,8,112,97,116,104,95,115,101,112,218,19, + 95,98,111,111,116,115,116,114,97,112,95,101,120,116,101,114, + 110,97,108,90,10,95,112,97,116,104,95,115,116,97,116,218, + 7,79,83,69,114,114,111,114,218,10,86,97,108,117,101,69, + 114,114,111,114,90,11,95,112,97,116,104,95,115,112,108,105, + 116,218,6,97,112,112,101,110,100,90,7,115,116,95,109,111, + 100,101,218,20,95,122,105,112,95,100,105,114,101,99,116,111, + 114,121,95,99,97,99,104,101,218,8,75,101,121,69,114,114, + 111,114,218,15,95,114,101,97,100,95,100,105,114,101,99,116, + 111,114,121,218,6,95,102,105,108,101,115,218,7,97,114,99, + 104,105,118,101,218,10,95,112,97,116,104,95,106,111,105,110, + 218,6,112,114,101,102,105,120,41,8,218,4,115,101,108,102, + 114,13,0,0,0,114,17,0,0,0,114,31,0,0,0,90, + 2,115,116,90,7,100,105,114,110,97,109,101,90,8,98,97, + 115,101,110,97,109,101,218,5,102,105,108,101,115,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,8,95,95, + 105,110,105,116,95,95,63,0,0,0,115,58,0,0,0,0, + 1,10,1,8,1,10,1,4,1,12,1,4,1,12,2,4, + 2,2,1,14,1,16,3,14,1,8,1,12,1,4,1,16, + 3,14,2,12,1,4,2,2,1,12,1,12,1,8,1,14, + 1,6,1,6,2,22,1,8,1,122,20,122,105,112,105,109, + 112,111,114,116,101,114,46,95,95,105,110,105,116,95,95,78, + 99,3,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,4,0,0,0,67,0,0,0,115,78,0,0,0,116,0, + 124,0,124,1,131,2,125,3,124,3,100,1,117,1,114,26, + 124,0,103,0,102,2,83,0,116,1,124,0,124,1,131,2, + 125,4,116,2,124,0,124,4,131,2,114,70,100,1,124,0, + 106,3,155,0,116,4,155,0,124,4,155,0,157,3,103,1, + 102,2,83,0,100,1,103,0,102,2,83,0,41,2,97,239, + 1,0,0,102,105,110,100,95,108,111,97,100,101,114,40,102, + 117,108,108,110,97,109,101,44,32,112,97,116,104,61,78,111, + 110,101,41,32,45,62,32,115,101,108,102,44,32,115,116,114, + 32,111,114,32,78,111,110,101,46,10,10,32,32,32,32,32, + 32,32,32,83,101,97,114,99,104,32,102,111,114,32,97,32, + 109,111,100,117,108,101,32,115,112,101,99,105,102,105,101,100, + 32,98,121,32,39,102,117,108,108,110,97,109,101,39,46,32, + 39,102,117,108,108,110,97,109,101,39,32,109,117,115,116,32, + 98,101,32,116,104,101,10,32,32,32,32,32,32,32,32,102, + 117,108,108,121,32,113,117,97,108,105,102,105,101,100,32,40, + 100,111,116,116,101,100,41,32,109,111,100,117,108,101,32,110, + 97,109,101,46,32,73,116,32,114,101,116,117,114,110,115,32, + 116,104,101,32,122,105,112,105,109,112,111,114,116,101,114,10, + 32,32,32,32,32,32,32,32,105,110,115,116,97,110,99,101, + 32,105,116,115,101,108,102,32,105,102,32,116,104,101,32,109, + 111,100,117,108,101,32,119,97,115,32,102,111,117,110,100,44, + 32,97,32,115,116,114,105,110,103,32,99,111,110,116,97,105, + 110,105,110,103,32,116,104,101,10,32,32,32,32,32,32,32, + 32,102,117,108,108,32,112,97,116,104,32,110,97,109,101,32, + 105,102,32,105,116,39,115,32,112,111,115,115,105,98,108,121, + 32,97,32,112,111,114,116,105,111,110,32,111,102,32,97,32, + 110,97,109,101,115,112,97,99,101,32,112,97,99,107,97,103, + 101,44,10,32,32,32,32,32,32,32,32,111,114,32,78,111, + 110,101,32,111,116,104,101,114,119,105,115,101,46,32,84,104, + 101,32,111,112,116,105,111,110,97,108,32,39,112,97,116,104, + 39,32,97,114,103,117,109,101,110,116,32,105,115,32,105,103, + 110,111,114,101,100,32,45,45,32,105,116,39,115,10,32,32, + 32,32,32,32,32,32,116,104,101,114,101,32,102,111,114,32, + 99,111,109,112,97,116,105,98,105,108,105,116,121,32,119,105, + 116,104,32,116,104,101,32,105,109,112,111,114,116,101,114,32, + 112,114,111,116,111,99,111,108,46,10,32,32,32,32,32,32, + 32,32,78,41,5,218,16,95,103,101,116,95,109,111,100,117, + 108,101,95,105,110,102,111,218,16,95,103,101,116,95,109,111, + 100,117,108,101,95,112,97,116,104,218,7,95,105,115,95,100, + 105,114,114,29,0,0,0,114,20,0,0,0,41,5,114,32, + 0,0,0,218,8,102,117,108,108,110,97,109,101,114,13,0, + 0,0,218,2,109,105,218,7,109,111,100,112,97,116,104,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,11, + 102,105,110,100,95,108,111,97,100,101,114,109,0,0,0,115, + 14,0,0,0,0,10,10,1,8,2,8,7,10,1,10,4, + 24,2,122,23,122,105,112,105,109,112,111,114,116,101,114,46, + 102,105,110,100,95,108,111,97,100,101,114,99,3,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,4,0,0,0, + 67,0,0,0,115,16,0,0,0,124,0,160,0,124,1,124, + 2,161,2,100,1,25,0,83,0,41,2,97,139,1,0,0, + 102,105,110,100,95,109,111,100,117,108,101,40,102,117,108,108, + 110,97,109,101,44,32,112,97,116,104,61,78,111,110,101,41, + 32,45,62,32,115,101,108,102,32,111,114,32,78,111,110,101, + 46,10,10,32,32,32,32,32,32,32,32,83,101,97,114,99, + 104,32,102,111,114,32,97,32,109,111,100,117,108,101,32,115, + 112,101,99,105,102,105,101,100,32,98,121,32,39,102,117,108, + 108,110,97,109,101,39,46,32,39,102,117,108,108,110,97,109, + 101,39,32,109,117,115,116,32,98,101,32,116,104,101,10,32, + 32,32,32,32,32,32,32,102,117,108,108,121,32,113,117,97, + 108,105,102,105,101,100,32,40,100,111,116,116,101,100,41,32, + 109,111,100,117,108,101,32,110,97,109,101,46,32,73,116,32, + 114,101,116,117,114,110,115,32,116,104,101,32,122,105,112,105, + 109,112,111,114,116,101,114,10,32,32,32,32,32,32,32,32, + 105,110,115,116,97,110,99,101,32,105,116,115,101,108,102,32, + 105,102,32,116,104,101,32,109,111,100,117,108,101,32,119,97, + 115,32,102,111,117,110,100,44,32,111,114,32,78,111,110,101, + 32,105,102,32,105,116,32,119,97,115,110,39,116,46,10,32, + 32,32,32,32,32,32,32,84,104,101,32,111,112,116,105,111, + 110,97,108,32,39,112,97,116,104,39,32,97,114,103,117,109, + 101,110,116,32,105,115,32,105,103,110,111,114,101,100,32,45, + 45,32,105,116,39,115,32,116,104,101,114,101,32,102,111,114, + 32,99,111,109,112,97,116,105,98,105,108,105,116,121,10,32, + 32,32,32,32,32,32,32,119,105,116,104,32,116,104,101,32, + 105,109,112,111,114,116,101,114,32,112,114,111,116,111,99,111, + 108,46,10,32,32,32,32,32,32,32,32,114,0,0,0,0, + 41,1,114,41,0,0,0,41,3,114,32,0,0,0,114,38, + 0,0,0,114,13,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,11,102,105,110,100,95,109,111, + 100,117,108,101,141,0,0,0,115,2,0,0,0,0,9,122, + 23,122,105,112,105,109,112,111,114,116,101,114,46,102,105,110, + 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,3,0,0,0,67,0,0, + 0,115,20,0,0,0,116,0,124,0,124,1,131,2,92,3, + 125,2,125,3,125,4,124,2,83,0,41,1,122,163,103,101, + 116,95,99,111,100,101,40,102,117,108,108,110,97,109,101,41, + 32,45,62,32,99,111,100,101,32,111,98,106,101,99,116,46, + 10,10,32,32,32,32,32,32,32,32,82,101,116,117,114,110, + 32,116,104,101,32,99,111,100,101,32,111,98,106,101,99,116, + 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, + 101,100,32,109,111,100,117,108,101,46,32,82,97,105,115,101, + 32,90,105,112,73,109,112,111,114,116,69,114,114,111,114,10, + 32,32,32,32,32,32,32,32,105,102,32,116,104,101,32,109, + 111,100,117,108,101,32,99,111,117,108,100,110,39,116,32,98, + 101,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, + 32,169,1,218,16,95,103,101,116,95,109,111,100,117,108,101, + 95,99,111,100,101,169,5,114,32,0,0,0,114,38,0,0, + 0,218,4,99,111,100,101,218,9,105,115,112,97,99,107,97, + 103,101,114,40,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,8,103,101,116,95,99,111,100,101, + 153,0,0,0,115,4,0,0,0,0,6,16,1,122,20,122, + 105,112,105,109,112,111,114,116,101,114,46,103,101,116,95,99, + 111,100,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,8,0,0,0,67,0,0,0,115,116,0,0, + 0,116,0,114,16,124,1,160,1,116,0,116,2,161,2,125, + 1,124,1,125,2,124,1,160,3,124,0,106,4,116,2,23, + 0,161,1,114,58,124,1,116,5,124,0,106,4,116,2,23, + 0,131,1,100,1,133,2,25,0,125,2,122,14,124,0,106, + 6,124,2,25,0,125,3,87,0,110,30,4,0,116,7,121, + 102,1,0,1,0,1,0,116,8,100,2,100,3,124,2,131, + 3,130,1,89,0,110,2,48,0,116,9,124,0,106,4,124, + 3,131,2,83,0,41,4,122,154,103,101,116,95,100,97,116, + 97,40,112,97,116,104,110,97,109,101,41,32,45,62,32,115, + 116,114,105,110,103,32,119,105,116,104,32,102,105,108,101,32, + 100,97,116,97,46,10,10,32,32,32,32,32,32,32,32,82, + 101,116,117,114,110,32,116,104,101,32,100,97,116,97,32,97, + 115,115,111,99,105,97,116,101,100,32,119,105,116,104,32,39, + 112,97,116,104,110,97,109,101,39,46,32,82,97,105,115,101, + 32,79,83,69,114,114,111,114,32,105,102,10,32,32,32,32, + 32,32,32,32,116,104,101,32,102,105,108,101,32,119,97,115, + 110,39,116,32,102,111,117,110,100,46,10,32,32,32,32,32, + 32,32,32,78,114,0,0,0,0,218,0,41,10,114,18,0, + 0,0,114,19,0,0,0,114,20,0,0,0,218,10,115,116, + 97,114,116,115,119,105,116,104,114,29,0,0,0,218,3,108, + 101,110,114,28,0,0,0,114,26,0,0,0,114,22,0,0, + 0,218,9,95,103,101,116,95,100,97,116,97,41,4,114,32, + 0,0,0,218,8,112,97,116,104,110,97,109,101,90,3,107, + 101,121,218,9,116,111,99,95,101,110,116,114,121,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,8,103,101, + 116,95,100,97,116,97,163,0,0,0,115,20,0,0,0,0, + 6,4,1,12,2,4,1,16,1,22,2,2,1,14,1,12, + 1,18,1,122,20,122,105,112,105,109,112,111,114,116,101,114, + 46,103,101,116,95,100,97,116,97,99,2,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,3,0,0,0,67,0, + 0,0,115,20,0,0,0,116,0,124,0,124,1,131,2,92, + 3,125,2,125,3,125,4,124,4,83,0,41,1,122,106,103, + 101,116,95,102,105,108,101,110,97,109,101,40,102,117,108,108, + 110,97,109,101,41,32,45,62,32,102,105,108,101,110,97,109, + 101,32,115,116,114,105,110,103,46,10,10,32,32,32,32,32, + 32,32,32,82,101,116,117,114,110,32,116,104,101,32,102,105, + 108,101,110,97,109,101,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,46, + 10,32,32,32,32,32,32,32,32,114,43,0,0,0,114,45, 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,8,95,95,114,101,112,114,95,95,34,1,0,0, - 115,2,0,0,0,0,1,122,20,122,105,112,105,109,112,111, - 114,116,101,114,46,95,95,114,101,112,114,95,95,41,1,78, - 41,1,78,41,15,114,6,0,0,0,114,7,0,0,0,114, - 8,0,0,0,218,7,95,95,100,111,99,95,95,114,34,0, - 0,0,114,41,0,0,0,114,42,0,0,0,114,48,0,0, - 0,114,55,0,0,0,114,56,0,0,0,114,64,0,0,0, - 114,65,0,0,0,114,78,0,0,0,114,82,0,0,0,114, - 83,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,4,0,0,0,45,0,0, - 0,115,24,0,0,0,8,1,4,17,8,46,10,32,10,12, - 8,10,8,21,8,11,8,26,8,13,8,38,8,18,122,12, - 95,95,105,110,105,116,95,95,46,112,121,99,84,114,60,0, - 0,0,70,41,3,122,4,46,112,121,99,84,70,41,3,114, - 61,0,0,0,70,70,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, - 20,0,0,0,124,0,106,0,124,1,160,1,100,1,161,1, - 100,2,25,0,23,0,83,0,41,3,78,218,1,46,233,2, - 0,0,0,41,2,114,31,0,0,0,218,10,114,112,97,114, - 116,105,116,105,111,110,41,2,114,32,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,36,0,0,0,52,1,0,0,115,2,0,0,0,0, - 1,114,36,0,0,0,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,2,0,0,0,67,0,0,0,115, - 18,0,0,0,124,1,116,0,23,0,125,2,124,2,124,0, - 106,1,118,0,83,0,169,1,78,41,2,114,20,0,0,0, - 114,28,0,0,0,41,3,114,32,0,0,0,114,13,0,0, - 0,90,7,100,105,114,112,97,116,104,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,37,0,0,0,56,1, - 0,0,115,4,0,0,0,0,4,8,2,114,37,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,4,0,0,0,67,0,0,0,115,56,0,0,0,116,0, - 124,0,124,1,131,2,125,2,116,1,68,0,93,36,92,3, - 125,3,125,4,125,5,124,2,124,3,23,0,125,6,124,6, - 124,0,106,2,118,0,114,14,124,5,2,0,1,0,83,0, - 113,14,100,0,83,0,114,88,0,0,0,41,3,114,36,0, - 0,0,218,16,95,122,105,112,95,115,101,97,114,99,104,111, - 114,100,101,114,114,28,0,0,0,41,7,114,32,0,0,0, - 114,38,0,0,0,114,13,0,0,0,218,6,115,117,102,102, - 105,120,218,10,105,115,98,121,116,101,99,111,100,101,114,47, - 0,0,0,114,63,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,114,35,0,0,0,65,1,0,0, - 115,12,0,0,0,0,1,10,1,14,1,8,1,10,1,10, - 1,114,35,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,26,0,0,0,9,0,0,0,67,0,0,0,115, - 2,5,0,0,122,14,116,0,160,1,124,0,161,1,125,1, - 87,0,110,36,4,0,116,2,121,50,1,0,1,0,1,0, - 116,3,100,1,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,124,1,144,4,143,164,1,0, - 122,36,124,1,160,4,116,5,11,0,100,3,161,2,1,0, - 124,1,160,6,161,0,125,2,124,1,160,7,116,5,161,1, - 125,3,87,0,110,36,4,0,116,2,121,132,1,0,1,0, - 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, - 141,2,130,1,89,0,110,2,48,0,116,8,124,3,131,1, - 116,5,107,3,114,164,116,3,100,4,124,0,155,2,157,2, - 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2, - 25,0,116,9,107,3,144,1,114,170,122,24,124,1,160,4, - 100,6,100,3,161,2,1,0,124,1,160,6,161,0,125,4, - 87,0,110,36,4,0,116,2,121,242,1,0,1,0,1,0, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,116,10,124,4,116,11,24,0, - 116,5,24,0,100,6,131,2,125,5,122,22,124,1,160,4, - 124,5,161,1,1,0,124,1,160,7,161,0,125,6,87,0, - 110,38,4,0,116,2,144,1,121,66,1,0,1,0,1,0, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,89,0,110,2,48,0,124,6,160,12,116,9,161,1, - 125,7,124,7,100,6,107,0,144,1,114,106,116,3,100,7, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,6, - 124,7,124,7,116,5,23,0,133,2,25,0,125,3,116,8, - 124,3,131,1,116,5,107,3,144,1,114,154,116,3,100,8, - 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,4, - 116,8,124,6,131,1,24,0,124,7,23,0,125,2,116,13, - 124,3,100,9,100,10,133,2,25,0,131,1,125,8,116,13, - 124,3,100,10,100,11,133,2,25,0,131,1,125,9,124,2, - 124,8,107,0,144,1,114,230,116,3,100,12,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,124,2,124,9,107,0, - 144,2,114,2,116,3,100,13,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,124,2,124,8,56,0,125,2,124,2, - 124,9,24,0,125,10,124,10,100,6,107,0,144,2,114,46, - 116,3,100,14,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,105,0,125,11,100,6,125,12,122,14,124,1,160,4, - 124,2,161,1,1,0,87,0,110,38,4,0,116,2,144,2, - 121,106,1,0,1,0,1,0,116,3,100,4,124,0,155,2, - 157,2,124,0,100,2,141,2,130,1,89,0,110,2,48,0, - 124,1,160,7,100,15,161,1,125,3,116,8,124,3,131,1, - 100,5,107,0,144,2,114,140,116,14,100,16,131,1,130,1, - 124,3,100,0,100,5,133,2,25,0,100,17,107,3,144,2, - 114,162,144,4,113,208,116,8,124,3,131,1,100,15,107,3, - 144,2,114,184,116,14,100,16,131,1,130,1,116,15,124,3, - 100,18,100,19,133,2,25,0,131,1,125,13,116,15,124,3, - 100,19,100,9,133,2,25,0,131,1,125,14,116,15,124,3, - 100,9,100,20,133,2,25,0,131,1,125,15,116,15,124,3, - 100,20,100,10,133,2,25,0,131,1,125,16,116,13,124,3, - 100,10,100,11,133,2,25,0,131,1,125,17,116,13,124,3, - 100,11,100,21,133,2,25,0,131,1,125,18,116,13,124,3, - 100,21,100,22,133,2,25,0,131,1,125,4,116,15,124,3, - 100,22,100,23,133,2,25,0,131,1,125,19,116,15,124,3, - 100,23,100,24,133,2,25,0,131,1,125,20,116,15,124,3, - 100,24,100,25,133,2,25,0,131,1,125,21,116,13,124,3, - 100,26,100,15,133,2,25,0,131,1,125,22,124,19,124,20, - 23,0,124,21,23,0,125,8,124,22,124,9,107,4,144,3, - 114,144,116,3,100,27,124,0,155,2,157,2,124,0,100,2, - 141,2,130,1,124,22,124,10,55,0,125,22,122,14,124,1, - 160,7,124,19,161,1,125,23,87,0,110,38,4,0,116,2, - 144,3,121,204,1,0,1,0,1,0,116,3,100,4,124,0, - 155,2,157,2,124,0,100,2,141,2,130,1,89,0,110,2, - 48,0,116,8,124,23,131,1,124,19,107,3,144,3,114,238, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,122,50,116,8,124,1,160,7,124,8,124,19,24,0, - 161,1,131,1,124,8,124,19,24,0,107,3,144,4,114,30, - 116,3,100,4,124,0,155,2,157,2,124,0,100,2,141,2, - 130,1,87,0,110,38,4,0,116,2,144,4,121,70,1,0, - 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, - 100,2,141,2,130,1,89,0,110,2,48,0,124,13,100,28, - 64,0,144,4,114,92,124,23,160,16,161,0,125,23,110,52, - 122,14,124,23,160,16,100,29,161,1,125,23,87,0,110,36, - 4,0,116,17,144,4,121,142,1,0,1,0,1,0,124,23, - 160,16,100,30,161,1,160,18,116,19,161,1,125,23,89,0, - 110,2,48,0,124,23,160,20,100,31,116,21,161,2,125,23, - 116,22,160,23,124,0,124,23,161,2,125,24,124,24,124,14, - 124,18,124,4,124,22,124,15,124,16,124,17,102,8,125,25, - 124,25,124,11,124,23,60,0,124,12,100,32,55,0,125,12, - 144,2,113,108,87,0,100,0,4,0,4,0,131,3,1,0, - 110,18,49,0,144,4,115,230,48,0,1,0,1,0,1,0, - 89,0,1,0,116,24,160,25,100,33,124,12,124,0,161,3, - 1,0,124,11,83,0,41,34,78,122,21,99,97,110,39,116, - 32,111,112,101,110,32,90,105,112,32,102,105,108,101,58,32, - 114,12,0,0,0,114,86,0,0,0,250,21,99,97,110,39, - 116,32,114,101,97,100,32,90,105,112,32,102,105,108,101,58, - 32,233,4,0,0,0,114,0,0,0,0,122,16,110,111,116, - 32,97,32,90,105,112,32,102,105,108,101,58,32,122,18,99, - 111,114,114,117,112,116,32,90,105,112,32,102,105,108,101,58, - 32,233,12,0,0,0,233,16,0,0,0,233,20,0,0,0, - 122,28,98,97,100,32,99,101,110,116,114,97,108,32,100,105, - 114,101,99,116,111,114,121,32,115,105,122,101,58,32,122,30, - 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101, - 99,116,111,114,121,32,111,102,102,115,101,116,58,32,122,38, - 98,97,100,32,99,101,110,116,114,97,108,32,100,105,114,101, - 99,116,111,114,121,32,115,105,122,101,32,111,114,32,111,102, - 102,115,101,116,58,32,233,46,0,0,0,250,27,69,79,70, - 32,114,101,97,100,32,119,104,101,114,101,32,110,111,116,32, - 101,120,112,101,99,116,101,100,115,4,0,0,0,80,75,1, - 2,233,8,0,0,0,233,10,0,0,0,233,14,0,0,0, - 233,24,0,0,0,233,28,0,0,0,233,30,0,0,0,233, - 32,0,0,0,233,34,0,0,0,233,42,0,0,0,122,25, - 98,97,100,32,108,111,99,97,108,32,104,101,97,100,101,114, - 32,111,102,102,115,101,116,58,32,105,0,8,0,0,218,5, - 97,115,99,105,105,90,6,108,97,116,105,110,49,250,1,47, - 114,5,0,0,0,122,33,122,105,112,105,109,112,111,114,116, - 58,32,102,111,117,110,100,32,123,125,32,110,97,109,101,115, - 32,105,110,32,123,33,114,125,41,26,218,3,95,105,111,218, - 9,111,112,101,110,95,99,111,100,101,114,22,0,0,0,114, - 3,0,0,0,218,4,115,101,101,107,218,20,69,78,68,95, - 67,69,78,84,82,65,76,95,68,73,82,95,83,73,90,69, - 90,4,116,101,108,108,218,4,114,101,97,100,114,51,0,0, - 0,218,18,83,84,82,73,78,71,95,69,78,68,95,65,82, - 67,72,73,86,69,218,3,109,97,120,218,15,77,65,88,95, - 67,79,77,77,69,78,84,95,76,69,78,218,5,114,102,105, - 110,100,114,2,0,0,0,218,8,69,79,70,69,114,114,111, - 114,114,1,0,0,0,114,62,0,0,0,218,18,85,110,105, - 99,111,100,101,68,101,99,111,100,101,69,114,114,111,114,218, - 9,116,114,97,110,115,108,97,116,101,218,11,99,112,52,51, - 55,95,116,97,98,108,101,114,19,0,0,0,114,20,0,0, - 0,114,21,0,0,0,114,30,0,0,0,114,76,0,0,0, - 114,77,0,0,0,41,26,114,29,0,0,0,218,2,102,112, - 90,15,104,101,97,100,101,114,95,112,111,115,105,116,105,111, - 110,218,6,98,117,102,102,101,114,218,9,102,105,108,101,95, - 115,105,122,101,90,17,109,97,120,95,99,111,109,109,101,110, - 116,95,115,116,97,114,116,218,4,100,97,116,97,90,3,112, - 111,115,218,11,104,101,97,100,101,114,95,115,105,122,101,90, - 13,104,101,97,100,101,114,95,111,102,102,115,101,116,90,10, - 97,114,99,95,111,102,102,115,101,116,114,33,0,0,0,218, - 5,99,111,117,110,116,218,5,102,108,97,103,115,218,8,99, - 111,109,112,114,101,115,115,218,4,116,105,109,101,218,4,100, - 97,116,101,218,3,99,114,99,218,9,100,97,116,97,95,115, - 105,122,101,218,9,110,97,109,101,95,115,105,122,101,218,10, - 101,120,116,114,97,95,115,105,122,101,90,12,99,111,109,109, - 101,110,116,95,115,105,122,101,218,11,102,105,108,101,95,111, - 102,102,115,101,116,114,59,0,0,0,114,13,0,0,0,218, - 1,116,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,27,0,0,0,96,1,0,0,115,212,0,0,0,0, - 1,2,1,14,1,12,1,24,2,8,1,2,1,14,1,8, - 1,14,1,12,1,24,1,12,1,18,1,18,3,2,1,12, - 1,12,1,12,1,10,1,2,255,12,2,8,1,2,255,2, - 1,2,255,4,2,2,1,10,1,12,1,14,1,10,1,2, - 255,12,2,10,1,10,1,10,1,2,255,6,2,16,1,14, - 1,10,1,2,255,6,2,16,2,16,1,16,1,10,1,18, - 1,10,1,18,1,8,1,8,1,10,1,18,2,4,2,4, - 1,2,1,14,1,14,1,24,2,10,1,14,1,8,2,18, - 1,4,1,14,1,8,1,16,1,16,1,16,1,16,1,16, - 1,16,1,16,1,16,1,16,1,16,1,16,1,12,1,10, - 1,18,1,8,2,2,1,14,1,14,1,24,1,14,1,18, - 4,2,1,28,1,22,1,14,1,24,2,10,2,10,3,2, - 1,14,1,14,1,22,2,12,1,12,1,20,1,8,1,44, - 1,14,1,114,27,0,0,0,117,190,1,0,0,0,1,2, - 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, - 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, - 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50, - 51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66, - 67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82, - 83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98, - 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114, - 115,116,117,118,119,120,121,122,123,124,125,126,127,195,135,195, - 188,195,169,195,162,195,164,195,160,195,165,195,167,195,170,195, - 171,195,168,195,175,195,174,195,172,195,132,195,133,195,137,195, - 166,195,134,195,180,195,182,195,178,195,187,195,185,195,191,195, - 150,195,156,194,162,194,163,194,165,226,130,167,198,146,195,161, - 195,173,195,179,195,186,195,177,195,145,194,170,194,186,194,191, - 226,140,144,194,172,194,189,194,188,194,161,194,171,194,187,226, - 150,145,226,150,146,226,150,147,226,148,130,226,148,164,226,149, - 161,226,149,162,226,149,150,226,149,149,226,149,163,226,149,145, - 226,149,151,226,149,157,226,149,156,226,149,155,226,148,144,226, - 148,148,226,148,180,226,148,172,226,148,156,226,148,128,226,148, - 188,226,149,158,226,149,159,226,149,154,226,149,148,226,149,169, - 226,149,166,226,149,160,226,149,144,226,149,172,226,149,167,226, - 149,168,226,149,164,226,149,165,226,149,153,226,149,152,226,149, - 146,226,149,147,226,149,171,226,149,170,226,148,152,226,148,140, - 226,150,136,226,150,132,226,150,140,226,150,144,226,150,128,206, - 177,195,159,206,147,207,128,206,163,207,131,194,181,207,132,206, - 166,206,152,206,169,206,180,226,136,158,207,134,206,181,226,136, - 169,226,137,161,194,177,226,137,165,226,137,164,226,140,160,226, - 140,161,195,183,226,137,136,194,176,226,136,153,194,183,226,136, - 154,226,129,191,194,178,226,150,160,194,160,99,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0, - 67,0,0,0,115,110,0,0,0,116,0,114,22,116,1,160, - 2,100,1,161,1,1,0,116,3,100,2,131,1,130,1,100, - 3,97,0,122,62,122,16,100,4,100,5,108,4,109,5,125, - 0,1,0,87,0,110,36,4,0,116,6,121,80,1,0,1, - 0,1,0,116,1,160,2,100,1,161,1,1,0,116,3,100, - 2,131,1,130,1,89,0,110,2,48,0,87,0,100,6,97, - 0,110,6,100,6,97,0,48,0,116,1,160,2,100,7,161, - 1,1,0,124,0,83,0,41,8,78,122,27,122,105,112,105, - 109,112,111,114,116,58,32,122,108,105,98,32,85,78,65,86, - 65,73,76,65,66,76,69,250,41,99,97,110,39,116,32,100, - 101,99,111,109,112,114,101,115,115,32,100,97,116,97,59,32, - 122,108,105,98,32,110,111,116,32,97,118,97,105,108,97,98, - 108,101,84,114,0,0,0,0,169,1,218,10,100,101,99,111, - 109,112,114,101,115,115,70,122,25,122,105,112,105,109,112,111, - 114,116,58,32,122,108,105,98,32,97,118,97,105,108,97,98, - 108,101,41,7,218,15,95,105,109,112,111,114,116,105,110,103, - 95,122,108,105,98,114,76,0,0,0,114,77,0,0,0,114, - 3,0,0,0,90,4,122,108,105,98,114,141,0,0,0,218, - 9,69,120,99,101,112,116,105,111,110,114,140,0,0,0,114, - 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,20, - 95,103,101,116,95,100,101,99,111,109,112,114,101,115,115,95, - 102,117,110,99,254,1,0,0,115,24,0,0,0,0,2,4, - 3,10,1,8,2,4,1,4,1,16,1,12,1,10,1,16, - 2,12,2,10,1,114,144,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,17,0,0,0,9,0,0,0,67, - 0,0,0,115,144,1,0,0,124,1,92,8,125,2,125,3, - 125,4,125,5,125,6,125,7,125,8,125,9,124,4,100,1, - 107,0,114,36,116,0,100,2,131,1,130,1,116,1,160,2, - 124,0,161,1,144,1,143,14,125,10,122,14,124,10,160,3, - 124,6,161,1,1,0,87,0,110,36,4,0,116,4,121,100, - 1,0,1,0,1,0,116,0,100,3,124,0,155,2,157,2, - 124,0,100,4,141,2,130,1,89,0,110,2,48,0,124,10, - 160,5,100,5,161,1,125,11,116,6,124,11,131,1,100,5, - 107,3,114,132,116,7,100,6,131,1,130,1,124,11,100,0, - 100,7,133,2,25,0,100,8,107,3,114,166,116,0,100,9, - 124,0,155,2,157,2,124,0,100,4,141,2,130,1,116,8, - 124,11,100,10,100,11,133,2,25,0,131,1,125,12,116,8, - 124,11,100,11,100,5,133,2,25,0,131,1,125,13,100,5, - 124,12,23,0,124,13,23,0,125,14,124,6,124,14,55,0, - 125,6,122,14,124,10,160,3,124,6,161,1,1,0,87,0, - 110,38,4,0,116,4,144,1,121,14,1,0,1,0,1,0, - 116,0,100,3,124,0,155,2,157,2,124,0,100,4,141,2, - 130,1,89,0,110,2,48,0,124,10,160,5,124,4,161,1, - 125,15,116,6,124,15,131,1,124,4,107,3,144,1,114,48, - 116,4,100,12,131,1,130,1,87,0,100,0,4,0,4,0, - 131,3,1,0,110,18,49,0,144,1,115,70,48,0,1,0, - 1,0,1,0,89,0,1,0,124,3,100,1,107,2,144,1, - 114,94,124,15,83,0,122,10,116,9,131,0,125,16,87,0, - 110,28,4,0,116,10,144,1,121,132,1,0,1,0,1,0, - 116,0,100,13,131,1,130,1,89,0,110,2,48,0,124,16, - 124,15,100,14,131,2,83,0,41,15,78,114,0,0,0,0, - 122,18,110,101,103,97,116,105,118,101,32,100,97,116,97,32, - 115,105,122,101,114,92,0,0,0,114,12,0,0,0,114,104, - 0,0,0,114,98,0,0,0,114,93,0,0,0,115,4,0, - 0,0,80,75,3,4,122,23,98,97,100,32,108,111,99,97, - 108,32,102,105,108,101,32,104,101,97,100,101,114,58,32,233, - 26,0,0,0,114,103,0,0,0,122,26,122,105,112,105,109, - 112,111,114,116,58,32,99,97,110,39,116,32,114,101,97,100, - 32,100,97,116,97,114,139,0,0,0,105,241,255,255,255,41, - 11,114,3,0,0,0,114,110,0,0,0,114,111,0,0,0, - 114,112,0,0,0,114,22,0,0,0,114,114,0,0,0,114, - 51,0,0,0,114,119,0,0,0,114,1,0,0,0,114,144, - 0,0,0,114,143,0,0,0,41,17,114,29,0,0,0,114, - 54,0,0,0,90,8,100,97,116,97,112,97,116,104,114,130, - 0,0,0,114,134,0,0,0,114,125,0,0,0,114,137,0, - 0,0,114,131,0,0,0,114,132,0,0,0,114,133,0,0, - 0,114,123,0,0,0,114,124,0,0,0,114,135,0,0,0, - 114,136,0,0,0,114,127,0,0,0,90,8,114,97,119,95, - 100,97,116,97,114,141,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,52,0,0,0,19,2,0, - 0,115,62,0,0,0,0,1,20,1,8,1,8,2,14,2, - 2,1,14,1,12,1,24,1,10,1,12,1,8,2,16,2, - 18,2,16,1,16,1,12,1,8,1,2,1,14,1,14,1, - 24,1,10,1,14,1,40,2,10,2,4,3,2,1,10,1, - 14,1,14,1,114,52,0,0,0,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,3,0,0,0,67,0, - 0,0,115,16,0,0,0,116,0,124,0,124,1,24,0,131, - 1,100,1,107,1,83,0,41,2,78,114,5,0,0,0,41, - 1,218,3,97,98,115,41,2,90,2,116,49,90,2,116,50, + 0,0,218,12,103,101,116,95,102,105,108,101,110,97,109,101, + 184,0,0,0,115,4,0,0,0,0,7,16,1,122,24,122, + 105,112,105,109,112,111,114,116,101,114,46,103,101,116,95,102, + 105,108,101,110,97,109,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,6,0,0,0,8,0,0,0,67,0,0,0, + 115,126,0,0,0,116,0,124,0,124,1,131,2,125,2,124, + 2,100,1,117,0,114,36,116,1,100,2,124,1,155,2,157, + 2,124,1,100,3,141,2,130,1,116,2,124,0,124,1,131, + 2,125,3,124,2,114,64,116,3,160,4,124,3,100,4,161, + 2,125,4,110,10,124,3,155,0,100,5,157,2,125,4,122, + 14,124,0,106,5,124,4,25,0,125,5,87,0,110,20,4, + 0,116,6,121,108,1,0,1,0,1,0,89,0,100,1,83, + 0,48,0,116,7,124,0,106,8,124,5,131,2,160,9,161, + 0,83,0,41,6,122,253,103,101,116,95,115,111,117,114,99, + 101,40,102,117,108,108,110,97,109,101,41,32,45,62,32,115, + 111,117,114,99,101,32,115,116,114,105,110,103,46,10,10,32, + 32,32,32,32,32,32,32,82,101,116,117,114,110,32,116,104, + 101,32,115,111,117,114,99,101,32,99,111,100,101,32,102,111, + 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, + 109,111,100,117,108,101,46,32,82,97,105,115,101,32,90,105, + 112,73,109,112,111,114,116,69,114,114,111,114,10,32,32,32, + 32,32,32,32,32,105,102,32,116,104,101,32,109,111,100,117, + 108,101,32,99,111,117,108,100,110,39,116,32,98,101,32,102, + 111,117,110,100,44,32,114,101,116,117,114,110,32,78,111,110, + 101,32,105,102,32,116,104,101,32,97,114,99,104,105,118,101, + 32,100,111,101,115,10,32,32,32,32,32,32,32,32,99,111, + 110,116,97,105,110,32,116,104,101,32,109,111,100,117,108,101, + 44,32,98,117,116,32,104,97,115,32,110,111,32,115,111,117, + 114,99,101,32,102,111,114,32,105,116,46,10,32,32,32,32, + 32,32,32,32,78,250,18,99,97,110,39,116,32,102,105,110, + 100,32,109,111,100,117,108,101,32,169,1,218,4,110,97,109, + 101,250,11,95,95,105,110,105,116,95,95,46,112,121,250,3, + 46,112,121,41,10,114,35,0,0,0,114,3,0,0,0,114, + 36,0,0,0,114,21,0,0,0,114,30,0,0,0,114,28, + 0,0,0,114,26,0,0,0,114,52,0,0,0,114,29,0, + 0,0,218,6,100,101,99,111,100,101,41,6,114,32,0,0, + 0,114,38,0,0,0,114,39,0,0,0,114,13,0,0,0, + 218,8,102,117,108,108,112,97,116,104,114,54,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,10, + 103,101,116,95,115,111,117,114,99,101,195,0,0,0,115,24, + 0,0,0,0,7,10,1,8,1,18,2,10,1,4,1,14, + 2,10,2,2,1,14,1,12,2,8,1,122,22,122,105,112, + 105,109,112,111,114,116,101,114,46,103,101,116,95,115,111,117, + 114,99,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,4,0,0,0,67,0,0,0,115,40,0,0, + 0,116,0,124,0,124,1,131,2,125,2,124,2,100,1,117, + 0,114,36,116,1,100,2,124,1,155,2,157,2,124,1,100, + 3,141,2,130,1,124,2,83,0,41,4,122,171,105,115,95, + 112,97,99,107,97,103,101,40,102,117,108,108,110,97,109,101, + 41,32,45,62,32,98,111,111,108,46,10,10,32,32,32,32, + 32,32,32,32,82,101,116,117,114,110,32,84,114,117,101,32, + 105,102,32,116,104,101,32,109,111,100,117,108,101,32,115,112, + 101,99,105,102,105,101,100,32,98,121,32,102,117,108,108,110, + 97,109,101,32,105,115,32,97,32,112,97,99,107,97,103,101, + 46,10,32,32,32,32,32,32,32,32,82,97,105,115,101,32, + 90,105,112,73,109,112,111,114,116,69,114,114,111,114,32,105, + 102,32,116,104,101,32,109,111,100,117,108,101,32,99,111,117, + 108,100,110,39,116,32,98,101,32,102,111,117,110,100,46,10, + 32,32,32,32,32,32,32,32,78,114,57,0,0,0,114,58, + 0,0,0,41,2,114,35,0,0,0,114,3,0,0,0,41, + 3,114,32,0,0,0,114,38,0,0,0,114,39,0,0,0, 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, - 9,95,101,113,95,109,116,105,109,101,65,2,0,0,115,2, - 0,0,0,0,2,114,147,0,0,0,99,5,0,0,0,0, - 0,0,0,0,0,0,0,14,0,0,0,8,0,0,0,67, - 0,0,0,115,56,1,0,0,124,3,124,2,100,1,156,2, - 125,5,122,18,116,0,160,1,124,4,124,3,124,5,161,3, - 125,6,87,0,110,20,4,0,116,2,121,48,1,0,1,0, - 1,0,89,0,100,0,83,0,48,0,124,6,100,2,64,0, - 100,3,107,3,125,7,124,7,114,178,124,6,100,4,64,0, - 100,3,107,3,125,8,116,3,106,4,100,5,107,3,114,176, - 124,8,115,102,116,3,106,4,100,6,107,2,114,176,116,5, - 124,0,124,2,131,2,125,9,124,9,100,0,117,1,114,176, - 116,3,160,6,116,0,106,7,124,9,161,2,125,10,122,20, - 116,0,160,8,124,4,124,10,124,3,124,5,161,4,1,0, - 87,0,110,20,4,0,116,2,121,174,1,0,1,0,1,0, - 89,0,100,0,83,0,48,0,110,84,116,9,124,0,124,2, - 131,2,92,2,125,11,125,12,124,11,144,1,114,6,116,10, - 116,11,124,4,100,7,100,8,133,2,25,0,131,1,124,11, - 131,2,114,242,116,11,124,4,100,8,100,9,133,2,25,0, - 131,1,124,12,107,3,144,1,114,6,116,12,160,13,100,10, - 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,14, - 160,15,124,4,100,9,100,0,133,2,25,0,161,1,125,13, - 116,16,124,13,116,17,131,2,144,1,115,52,116,18,100,11, - 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, - 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, - 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, - 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0, - 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121, - 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, - 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, - 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,41,19,114, - 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, - 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, - 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,90,18,95,118,97,108,105,100,97,116, - 101,95,104,97,115,104,95,112,121,99,218,29,95,103,101,116, - 95,109,116,105,109,101,95,97,110,100,95,115,105,122,101,95, - 111,102,95,115,111,117,114,99,101,114,147,0,0,0,114,2, - 0,0,0,114,76,0,0,0,114,77,0,0,0,218,7,109, - 97,114,115,104,97,108,90,5,108,111,97,100,115,114,15,0, - 0,0,218,10,95,99,111,100,101,95,116,121,112,101,218,9, - 84,121,112,101,69,114,114,111,114,41,14,114,32,0,0,0, - 114,53,0,0,0,114,63,0,0,0,114,38,0,0,0,114, - 126,0,0,0,90,11,101,120,99,95,100,101,116,97,105,108, - 115,114,129,0,0,0,90,10,104,97,115,104,95,98,97,115, - 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101, - 90,12,115,111,117,114,99,101,95,98,121,116,101,115,114,150, - 0,0,0,90,12,115,111,117,114,99,101,95,109,116,105,109, - 101,90,11,115,111,117,114,99,101,95,115,105,122,101,114,46, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,15,95,117,110,109,97,114,115,104,97,108,95,99, - 111,100,101,75,2,0,0,115,82,0,0,0,0,2,2,1, - 2,254,6,5,2,1,18,1,12,1,8,2,12,1,4,1, - 12,1,10,1,2,255,2,1,8,255,2,2,10,1,8,1, - 4,1,4,1,2,254,4,5,2,1,4,1,8,255,8,2, - 12,1,10,3,8,255,6,3,6,3,22,1,18,255,4,2, - 4,1,8,255,4,2,4,2,18,1,12,1,16,1,114,155, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, - 0,124,0,160,0,100,1,100,2,161,2,125,0,124,0,160, - 0,100,3,100,2,161,2,125,0,124,0,83,0,41,4,78, - 115,2,0,0,0,13,10,243,1,0,0,0,10,243,1,0, - 0,0,13,41,1,114,19,0,0,0,41,1,218,6,115,111, - 117,114,99,101,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,23,95,110,111,114,109,97,108,105,122,101,95, - 108,105,110,101,95,101,110,100,105,110,103,115,126,2,0,0, - 115,6,0,0,0,0,1,12,1,12,1,114,159,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,6,0,0,0,67,0,0,0,115,24,0,0,0,116,0, - 124,1,131,1,125,1,116,1,124,1,124,0,100,1,100,2, - 100,3,141,4,83,0,41,4,78,114,74,0,0,0,84,41, - 1,90,12,100,111,110,116,95,105,110,104,101,114,105,116,41, - 2,114,159,0,0,0,218,7,99,111,109,112,105,108,101,41, - 2,114,53,0,0,0,114,158,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,15,95,99,111,109, - 112,105,108,101,95,115,111,117,114,99,101,133,2,0,0,115, - 4,0,0,0,0,1,8,1,114,161,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,11,0, - 0,0,67,0,0,0,115,68,0,0,0,116,0,160,1,124, - 0,100,1,63,0,100,2,23,0,124,0,100,3,63,0,100, - 4,64,0,124,0,100,5,64,0,124,1,100,6,63,0,124, - 1,100,3,63,0,100,7,64,0,124,1,100,5,64,0,100, - 8,20,0,100,9,100,9,100,9,102,9,161,1,83,0,41, - 10,78,233,9,0,0,0,105,188,7,0,0,233,5,0,0, - 0,233,15,0,0,0,233,31,0,0,0,233,11,0,0,0, - 233,63,0,0,0,114,86,0,0,0,114,14,0,0,0,41, - 2,114,131,0,0,0,90,6,109,107,116,105,109,101,41,2, - 218,1,100,114,138,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,14,95,112,97,114,115,101,95, - 100,111,115,116,105,109,101,139,2,0,0,115,18,0,0,0, - 0,1,4,1,10,1,10,1,6,1,6,1,10,1,10,1, - 6,249,114,169,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,6,0,0,0,10,0,0,0,67,0,0,0, - 115,114,0,0,0,122,82,124,1,100,1,100,0,133,2,25, - 0,100,2,118,0,115,22,74,0,130,1,124,1,100,0,100, - 1,133,2,25,0,125,1,124,0,106,0,124,1,25,0,125, - 2,124,2,100,3,25,0,125,3,124,2,100,4,25,0,125, - 4,124,2,100,5,25,0,125,5,116,1,124,4,124,3,131, - 2,124,5,102,2,87,0,83,0,4,0,116,2,116,3,116, - 4,102,3,121,108,1,0,1,0,1,0,89,0,100,6,83, - 0,48,0,100,0,83,0,41,7,78,114,14,0,0,0,169, - 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0, - 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, - 0,0,41,5,114,28,0,0,0,114,169,0,0,0,114,26, - 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, - 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90, - 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, - 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0, - 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, - 1,18,1,114,151,0,0,0,99,2,0,0,0,0,0,0, + 10,105,115,95,112,97,99,107,97,103,101,221,0,0,0,115, + 8,0,0,0,0,6,10,1,8,1,18,1,122,22,122,105, + 112,105,109,112,111,114,116,101,114,46,105,115,95,112,97,99, + 107,97,103,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,8,0,0,0,8,0,0,0,67,0,0,0,115,246,0, + 0,0,116,0,124,0,124,1,131,2,92,3,125,2,125,3, + 125,4,116,1,106,2,160,3,124,1,161,1,125,5,124,5, + 100,1,117,0,115,46,116,4,124,5,116,5,131,2,115,64, + 116,5,124,1,131,1,125,5,124,5,116,1,106,2,124,1, + 60,0,124,0,124,5,95,6,122,84,124,3,114,108,116,7, + 124,0,124,1,131,2,125,6,116,8,160,9,124,0,106,10, + 124,6,161,2,125,7,124,7,103,1,124,5,95,11,116,12, + 124,5,100,2,131,2,115,124,116,13,124,5,95,13,116,8, + 160,14,124,5,106,15,124,1,124,4,161,3,1,0,116,16, + 124,2,124,5,106,15,131,2,1,0,87,0,110,22,1,0, + 1,0,1,0,116,1,106,2,124,1,61,0,130,0,89,0, + 110,2,48,0,122,14,116,1,106,2,124,1,25,0,125,5, + 87,0,110,34,4,0,116,17,121,226,1,0,1,0,1,0, + 116,18,100,3,124,1,155,2,100,4,157,3,131,1,130,1, + 89,0,110,2,48,0,116,19,160,20,100,5,124,1,124,4, + 161,3,1,0,124,5,83,0,41,6,122,245,108,111,97,100, + 95,109,111,100,117,108,101,40,102,117,108,108,110,97,109,101, + 41,32,45,62,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,32,32,32,32,76,111,97,100,32,116,104,101,32,109, + 111,100,117,108,101,32,115,112,101,99,105,102,105,101,100,32, + 98,121,32,39,102,117,108,108,110,97,109,101,39,46,32,39, + 102,117,108,108,110,97,109,101,39,32,109,117,115,116,32,98, + 101,32,116,104,101,10,32,32,32,32,32,32,32,32,102,117, + 108,108,121,32,113,117,97,108,105,102,105,101,100,32,40,100, + 111,116,116,101,100,41,32,109,111,100,117,108,101,32,110,97, + 109,101,46,32,73,116,32,114,101,116,117,114,110,115,32,116, + 104,101,32,105,109,112,111,114,116,101,100,10,32,32,32,32, + 32,32,32,32,109,111,100,117,108,101,44,32,111,114,32,114, + 97,105,115,101,115,32,90,105,112,73,109,112,111,114,116,69, + 114,114,111,114,32,105,102,32,105,116,32,119,97,115,110,39, + 116,32,102,111,117,110,100,46,10,32,32,32,32,32,32,32, + 32,78,218,12,95,95,98,117,105,108,116,105,110,115,95,95, + 122,14,76,111,97,100,101,100,32,109,111,100,117,108,101,32, + 122,25,32,110,111,116,32,102,111,117,110,100,32,105,110,32, + 115,121,115,46,109,111,100,117,108,101,115,122,30,105,109,112, + 111,114,116,32,123,125,32,35,32,108,111,97,100,101,100,32, + 102,114,111,109,32,90,105,112,32,123,125,41,21,114,44,0, + 0,0,218,3,115,121,115,218,7,109,111,100,117,108,101,115, + 218,3,103,101,116,114,15,0,0,0,218,12,95,109,111,100, + 117,108,101,95,116,121,112,101,218,10,95,95,108,111,97,100, + 101,114,95,95,114,36,0,0,0,114,21,0,0,0,114,30, + 0,0,0,114,29,0,0,0,90,8,95,95,112,97,116,104, + 95,95,218,7,104,97,115,97,116,116,114,114,66,0,0,0, + 90,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101, + 218,8,95,95,100,105,99,116,95,95,218,4,101,120,101,99, + 114,26,0,0,0,218,11,73,109,112,111,114,116,69,114,114, + 111,114,218,10,95,98,111,111,116,115,116,114,97,112,218,16, + 95,118,101,114,98,111,115,101,95,109,101,115,115,97,103,101, + 41,8,114,32,0,0,0,114,38,0,0,0,114,46,0,0, + 0,114,47,0,0,0,114,40,0,0,0,90,3,109,111,100, + 114,13,0,0,0,114,63,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,11,108,111,97,100,95, + 109,111,100,117,108,101,234,0,0,0,115,48,0,0,0,0, + 7,16,1,12,1,18,1,8,1,10,1,6,2,2,1,4, + 3,10,1,14,1,8,2,10,1,6,1,16,1,16,1,6, + 1,8,1,8,2,2,1,14,1,12,1,22,1,14,1,122, + 23,122,105,112,105,109,112,111,114,116,101,114,46,108,111,97, + 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, - 0,115,84,0,0,0,124,1,100,1,100,0,133,2,25,0, - 100,2,118,0,115,20,74,0,130,1,124,1,100,0,100,1, - 133,2,25,0,125,1,122,14,124,0,106,0,124,1,25,0, - 125,2,87,0,110,20,4,0,116,1,121,66,1,0,1,0, - 1,0,89,0,100,0,83,0,48,0,116,2,124,0,106,3, - 124,2,131,2,83,0,100,0,83,0,41,3,78,114,14,0, - 0,0,114,170,0,0,0,41,4,114,28,0,0,0,114,26, - 0,0,0,114,52,0,0,0,114,29,0,0,0,41,3,114, - 32,0,0,0,114,13,0,0,0,114,54,0,0,0,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,114,149,0, - 0,0,171,2,0,0,115,14,0,0,0,0,2,20,1,12, - 2,2,1,14,1,12,1,8,2,114,149,0,0,0,99,2, - 0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,9, - 0,0,0,67,0,0,0,115,196,0,0,0,116,0,124,0, - 124,1,131,2,125,2,116,1,68,0,93,158,92,3,125,3, - 125,4,125,5,124,2,124,3,23,0,125,6,116,2,106,3, - 100,1,124,0,106,4,116,5,124,6,100,2,100,3,141,5, - 1,0,122,14,124,0,106,6,124,6,25,0,125,7,87,0, - 110,18,4,0,116,7,121,86,1,0,1,0,1,0,89,0, - 113,14,48,0,124,7,100,4,25,0,125,8,116,8,124,0, - 106,4,124,7,131,2,125,9,124,4,114,130,116,9,124,0, - 124,8,124,6,124,1,124,9,131,5,125,10,110,10,116,10, - 124,8,124,9,131,2,125,10,124,10,100,0,117,0,114,150, - 113,14,124,7,100,4,25,0,125,8,124,10,124,5,124,8, - 102,3,2,0,1,0,83,0,113,14,116,11,100,5,124,1, - 155,2,157,2,124,1,100,6,141,2,130,1,100,0,83,0, - 41,7,78,122,13,116,114,121,105,110,103,32,123,125,123,125, - 123,125,114,86,0,0,0,41,1,90,9,118,101,114,98,111, - 115,105,116,121,114,0,0,0,0,114,57,0,0,0,114,58, - 0,0,0,41,12,114,36,0,0,0,114,89,0,0,0,114, - 76,0,0,0,114,77,0,0,0,114,29,0,0,0,114,20, - 0,0,0,114,28,0,0,0,114,26,0,0,0,114,52,0, - 0,0,114,155,0,0,0,114,161,0,0,0,114,3,0,0, - 0,41,11,114,32,0,0,0,114,38,0,0,0,114,13,0, - 0,0,114,90,0,0,0,114,91,0,0,0,114,47,0,0, - 0,114,63,0,0,0,114,54,0,0,0,114,40,0,0,0, - 114,126,0,0,0,114,46,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,44,0,0,0,186,2, - 0,0,115,36,0,0,0,0,1,10,1,14,1,8,1,22, - 1,2,1,14,1,12,1,6,2,8,1,12,1,4,1,18, - 2,10,1,8,3,2,1,8,1,16,2,114,44,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,64,0,0,0,115,60,0,0,0,101,0, - 90,1,100,0,90,2,100,1,90,3,100,2,90,4,100,3, - 100,4,132,0,90,5,100,5,100,6,132,0,90,6,100,7, - 100,8,132,0,90,7,100,9,100,10,132,0,90,8,100,11, - 100,12,132,0,90,9,100,13,83,0,41,14,114,80,0,0, - 0,122,165,80,114,105,118,97,116,101,32,99,108,97,115,115, - 32,117,115,101,100,32,116,111,32,115,117,112,112,111,114,116, - 32,90,105,112,73,109,112,111,114,116,46,103,101,116,95,114, - 101,115,111,117,114,99,101,95,114,101,97,100,101,114,40,41, - 46,10,10,32,32,32,32,84,104,105,115,32,99,108,97,115, - 115,32,105,115,32,97,108,108,111,119,101,100,32,116,111,32, - 114,101,102,101,114,101,110,99,101,32,97,108,108,32,116,104, - 101,32,105,110,110,97,114,100,115,32,97,110,100,32,112,114, - 105,118,97,116,101,32,112,97,114,116,115,32,111,102,10,32, - 32,32,32,116,104,101,32,122,105,112,105,109,112,111,114,116, - 101,114,46,10,32,32,32,32,70,99,3,0,0,0,0,0, + 0,115,64,0,0,0,122,20,124,0,160,0,124,1,161,1, + 115,18,87,0,100,1,83,0,87,0,110,20,4,0,116,1, + 121,40,1,0,1,0,1,0,89,0,100,1,83,0,48,0, + 100,2,100,3,108,2,109,3,125,2,1,0,124,2,124,0, + 124,1,131,2,83,0,41,4,122,204,82,101,116,117,114,110, + 32,116,104,101,32,82,101,115,111,117,114,99,101,82,101,97, + 100,101,114,32,102,111,114,32,97,32,112,97,99,107,97,103, + 101,32,105,110,32,97,32,122,105,112,32,102,105,108,101,46, + 10,10,32,32,32,32,32,32,32,32,73,102,32,39,102,117, + 108,108,110,97,109,101,39,32,105,115,32,97,32,112,97,99, + 107,97,103,101,32,119,105,116,104,105,110,32,116,104,101,32, + 122,105,112,32,102,105,108,101,44,32,114,101,116,117,114,110, + 32,116,104,101,10,32,32,32,32,32,32,32,32,39,82,101, + 115,111,117,114,99,101,82,101,97,100,101,114,39,32,111,98, + 106,101,99,116,32,102,111,114,32,116,104,101,32,112,97,99, + 107,97,103,101,46,32,32,79,116,104,101,114,119,105,115,101, + 32,114,101,116,117,114,110,32,78,111,110,101,46,10,32,32, + 32,32,32,32,32,32,78,114,0,0,0,0,41,1,218,9, + 90,105,112,82,101,97,100,101,114,41,4,114,65,0,0,0, + 114,3,0,0,0,90,17,105,109,112,111,114,116,108,105,98, + 46,114,101,97,100,101,114,115,114,79,0,0,0,41,3,114, + 32,0,0,0,114,38,0,0,0,114,79,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,218,19,103, + 101,116,95,114,101,115,111,117,114,99,101,95,114,101,97,100, + 101,114,16,1,0,0,115,14,0,0,0,0,6,2,1,10, + 1,10,1,12,1,8,1,12,1,122,31,122,105,112,105,109, + 112,111,114,116,101,114,46,103,101,116,95,114,101,115,111,117, + 114,99,101,95,114,101,97,100,101,114,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,67, + 0,0,0,115,24,0,0,0,100,1,124,0,106,0,155,0, + 116,1,155,0,124,0,106,2,155,0,100,2,157,5,83,0, + 41,3,78,122,21,60,122,105,112,105,109,112,111,114,116,101, + 114,32,111,98,106,101,99,116,32,34,122,2,34,62,41,3, + 114,29,0,0,0,114,20,0,0,0,114,31,0,0,0,41, + 1,114,32,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,8,95,95,114,101,112,114,95,95,31, + 1,0,0,115,2,0,0,0,0,1,122,20,122,105,112,105, + 109,112,111,114,116,101,114,46,95,95,114,101,112,114,95,95, + 41,1,78,41,1,78,41,15,114,6,0,0,0,114,7,0, + 0,0,114,8,0,0,0,218,7,95,95,100,111,99,95,95, + 114,34,0,0,0,114,41,0,0,0,114,42,0,0,0,114, + 48,0,0,0,114,55,0,0,0,114,56,0,0,0,114,64, + 0,0,0,114,65,0,0,0,114,78,0,0,0,114,80,0, + 0,0,114,81,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,9,0,0,0,114,10,0,0,0,114,4,0,0,0, + 45,0,0,0,115,24,0,0,0,8,1,4,17,8,46,10, + 32,10,12,8,10,8,21,8,11,8,26,8,13,8,38,8, + 15,122,12,95,95,105,110,105,116,95,95,46,112,121,99,84, + 114,60,0,0,0,70,41,3,122,4,46,112,121,99,84,70, + 41,3,114,61,0,0,0,70,70,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,67,0, + 0,0,115,20,0,0,0,124,0,106,0,124,1,160,1,100, + 1,161,1,100,2,25,0,23,0,83,0,41,3,78,218,1, + 46,233,2,0,0,0,41,2,114,31,0,0,0,218,10,114, + 112,97,114,116,105,116,105,111,110,41,2,114,32,0,0,0, + 114,38,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,36,0,0,0,49,1,0,0,115,2,0, + 0,0,0,1,114,36,0,0,0,99,2,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0, - 0,0,115,16,0,0,0,124,1,124,0,95,0,124,2,124, - 0,95,1,100,0,83,0,114,88,0,0,0,41,2,114,4, - 0,0,0,114,38,0,0,0,41,3,114,32,0,0,0,114, - 4,0,0,0,114,38,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,34,0,0,0,220,2,0, - 0,115,4,0,0,0,0,1,6,1,122,33,95,90,105,112, - 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, - 97,100,101,114,46,95,95,105,110,105,116,95,95,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,8,0, - 0,0,67,0,0,0,115,90,0,0,0,124,0,106,0,160, - 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124, - 1,155,0,157,3,125,3,100,3,100,4,108,2,109,3,125, - 4,1,0,122,18,124,4,124,0,106,4,160,5,124,3,161, - 1,131,1,87,0,83,0,4,0,116,6,121,84,1,0,1, - 0,1,0,116,7,124,3,131,1,130,1,89,0,110,2,48, - 0,100,0,83,0,41,5,78,114,85,0,0,0,114,109,0, - 0,0,114,0,0,0,0,41,1,218,7,66,121,116,101,115, - 73,79,41,8,114,38,0,0,0,114,19,0,0,0,90,2, - 105,111,114,176,0,0,0,114,4,0,0,0,114,55,0,0, - 0,114,22,0,0,0,218,17,70,105,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,41,5,114,32,0,0,0, - 218,8,114,101,115,111,117,114,99,101,218,16,102,117,108,108, - 110,97,109,101,95,97,115,95,112,97,116,104,114,13,0,0, - 0,114,176,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,13,111,112,101,110,95,114,101,115,111, - 117,114,99,101,224,2,0,0,115,14,0,0,0,0,1,14, - 1,14,1,12,1,2,1,18,1,12,1,122,38,95,90,105, - 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, - 101,97,100,101,114,46,111,112,101,110,95,114,101,115,111,117, - 114,99,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,8,0,0, - 0,116,0,130,1,100,0,83,0,114,88,0,0,0,41,1, - 114,177,0,0,0,41,2,114,32,0,0,0,114,178,0,0, + 0,0,115,18,0,0,0,124,1,116,0,23,0,125,2,124, + 2,124,0,106,1,118,0,83,0,169,1,78,41,2,114,20, + 0,0,0,114,28,0,0,0,41,3,114,32,0,0,0,114, + 13,0,0,0,90,7,100,105,114,112,97,116,104,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,37,0,0, + 0,53,1,0,0,115,4,0,0,0,0,4,8,2,114,37, + 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, + 7,0,0,0,4,0,0,0,67,0,0,0,115,56,0,0, + 0,116,0,124,0,124,1,131,2,125,2,116,1,68,0,93, + 36,92,3,125,3,125,4,125,5,124,2,124,3,23,0,125, + 6,124,6,124,0,106,2,118,0,114,14,124,5,2,0,1, + 0,83,0,113,14,100,0,83,0,114,86,0,0,0,41,3, + 114,36,0,0,0,218,16,95,122,105,112,95,115,101,97,114, + 99,104,111,114,100,101,114,114,28,0,0,0,41,7,114,32, + 0,0,0,114,38,0,0,0,114,13,0,0,0,218,6,115, + 117,102,102,105,120,218,10,105,115,98,121,116,101,99,111,100, + 101,114,47,0,0,0,114,63,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,114,35,0,0,0,62, + 1,0,0,115,12,0,0,0,0,1,10,1,14,1,8,1, + 10,1,10,1,114,35,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,26,0,0,0,9,0,0,0,67,0, + 0,0,115,2,5,0,0,122,14,116,0,160,1,124,0,161, + 1,125,1,87,0,110,36,4,0,116,2,121,50,1,0,1, + 0,1,0,116,3,100,1,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,89,0,110,2,48,0,124,1,144,4,143, + 164,1,0,122,36,124,1,160,4,116,5,11,0,100,3,161, + 2,1,0,124,1,160,6,161,0,125,2,124,1,160,7,116, + 5,161,1,125,3,87,0,110,36,4,0,116,2,121,132,1, + 0,1,0,1,0,116,3,100,4,124,0,155,2,157,2,124, + 0,100,2,141,2,130,1,89,0,110,2,48,0,116,8,124, + 3,131,1,116,5,107,3,114,164,116,3,100,4,124,0,155, + 2,157,2,124,0,100,2,141,2,130,1,124,3,100,0,100, + 5,133,2,25,0,116,9,107,3,144,1,114,170,122,24,124, + 1,160,4,100,6,100,3,161,2,1,0,124,1,160,6,161, + 0,125,4,87,0,110,36,4,0,116,2,121,242,1,0,1, + 0,1,0,116,3,100,4,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,89,0,110,2,48,0,116,10,124,4,116, + 11,24,0,116,5,24,0,100,6,131,2,125,5,122,22,124, + 1,160,4,124,5,161,1,1,0,124,1,160,7,161,0,125, + 6,87,0,110,38,4,0,116,2,144,1,121,66,1,0,1, + 0,1,0,116,3,100,4,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,89,0,110,2,48,0,124,6,160,12,116, + 9,161,1,125,7,124,7,100,6,107,0,144,1,114,106,116, + 3,100,7,124,0,155,2,157,2,124,0,100,2,141,2,130, + 1,124,6,124,7,124,7,116,5,23,0,133,2,25,0,125, + 3,116,8,124,3,131,1,116,5,107,3,144,1,114,154,116, + 3,100,8,124,0,155,2,157,2,124,0,100,2,141,2,130, + 1,124,4,116,8,124,6,131,1,24,0,124,7,23,0,125, + 2,116,13,124,3,100,9,100,10,133,2,25,0,131,1,125, + 8,116,13,124,3,100,10,100,11,133,2,25,0,131,1,125, + 9,124,2,124,8,107,0,144,1,114,230,116,3,100,12,124, + 0,155,2,157,2,124,0,100,2,141,2,130,1,124,2,124, + 9,107,0,144,2,114,2,116,3,100,13,124,0,155,2,157, + 2,124,0,100,2,141,2,130,1,124,2,124,8,56,0,125, + 2,124,2,124,9,24,0,125,10,124,10,100,6,107,0,144, + 2,114,46,116,3,100,14,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,105,0,125,11,100,6,125,12,122,14,124, + 1,160,4,124,2,161,1,1,0,87,0,110,38,4,0,116, + 2,144,2,121,106,1,0,1,0,1,0,116,3,100,4,124, + 0,155,2,157,2,124,0,100,2,141,2,130,1,89,0,110, + 2,48,0,124,1,160,7,100,15,161,1,125,3,116,8,124, + 3,131,1,100,5,107,0,144,2,114,140,116,14,100,16,131, + 1,130,1,124,3,100,0,100,5,133,2,25,0,100,17,107, + 3,144,2,114,162,144,4,113,208,116,8,124,3,131,1,100, + 15,107,3,144,2,114,184,116,14,100,16,131,1,130,1,116, + 15,124,3,100,18,100,19,133,2,25,0,131,1,125,13,116, + 15,124,3,100,19,100,9,133,2,25,0,131,1,125,14,116, + 15,124,3,100,9,100,20,133,2,25,0,131,1,125,15,116, + 15,124,3,100,20,100,10,133,2,25,0,131,1,125,16,116, + 13,124,3,100,10,100,11,133,2,25,0,131,1,125,17,116, + 13,124,3,100,11,100,21,133,2,25,0,131,1,125,18,116, + 13,124,3,100,21,100,22,133,2,25,0,131,1,125,4,116, + 15,124,3,100,22,100,23,133,2,25,0,131,1,125,19,116, + 15,124,3,100,23,100,24,133,2,25,0,131,1,125,20,116, + 15,124,3,100,24,100,25,133,2,25,0,131,1,125,21,116, + 13,124,3,100,26,100,15,133,2,25,0,131,1,125,22,124, + 19,124,20,23,0,124,21,23,0,125,8,124,22,124,9,107, + 4,144,3,114,144,116,3,100,27,124,0,155,2,157,2,124, + 0,100,2,141,2,130,1,124,22,124,10,55,0,125,22,122, + 14,124,1,160,7,124,19,161,1,125,23,87,0,110,38,4, + 0,116,2,144,3,121,204,1,0,1,0,1,0,116,3,100, + 4,124,0,155,2,157,2,124,0,100,2,141,2,130,1,89, + 0,110,2,48,0,116,8,124,23,131,1,124,19,107,3,144, + 3,114,238,116,3,100,4,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,122,50,116,8,124,1,160,7,124,8,124, + 19,24,0,161,1,131,1,124,8,124,19,24,0,107,3,144, + 4,114,30,116,3,100,4,124,0,155,2,157,2,124,0,100, + 2,141,2,130,1,87,0,110,38,4,0,116,2,144,4,121, + 70,1,0,1,0,1,0,116,3,100,4,124,0,155,2,157, + 2,124,0,100,2,141,2,130,1,89,0,110,2,48,0,124, + 13,100,28,64,0,144,4,114,92,124,23,160,16,161,0,125, + 23,110,52,122,14,124,23,160,16,100,29,161,1,125,23,87, + 0,110,36,4,0,116,17,144,4,121,142,1,0,1,0,1, + 0,124,23,160,16,100,30,161,1,160,18,116,19,161,1,125, + 23,89,0,110,2,48,0,124,23,160,20,100,31,116,21,161, + 2,125,23,116,22,160,23,124,0,124,23,161,2,125,24,124, + 24,124,14,124,18,124,4,124,22,124,15,124,16,124,17,102, + 8,125,25,124,25,124,11,124,23,60,0,124,12,100,32,55, + 0,125,12,144,2,113,108,87,0,100,0,4,0,4,0,131, + 3,1,0,110,18,49,0,144,4,115,230,48,0,1,0,1, + 0,1,0,89,0,1,0,116,24,160,25,100,33,124,12,124, + 0,161,3,1,0,124,11,83,0,41,34,78,122,21,99,97, + 110,39,116,32,111,112,101,110,32,90,105,112,32,102,105,108, + 101,58,32,114,12,0,0,0,114,84,0,0,0,250,21,99, + 97,110,39,116,32,114,101,97,100,32,90,105,112,32,102,105, + 108,101,58,32,233,4,0,0,0,114,0,0,0,0,122,16, + 110,111,116,32,97,32,90,105,112,32,102,105,108,101,58,32, + 122,18,99,111,114,114,117,112,116,32,90,105,112,32,102,105, + 108,101,58,32,233,12,0,0,0,233,16,0,0,0,233,20, + 0,0,0,122,28,98,97,100,32,99,101,110,116,114,97,108, + 32,100,105,114,101,99,116,111,114,121,32,115,105,122,101,58, + 32,122,30,98,97,100,32,99,101,110,116,114,97,108,32,100, + 105,114,101,99,116,111,114,121,32,111,102,102,115,101,116,58, + 32,122,38,98,97,100,32,99,101,110,116,114,97,108,32,100, + 105,114,101,99,116,111,114,121,32,115,105,122,101,32,111,114, + 32,111,102,102,115,101,116,58,32,233,46,0,0,0,250,27, + 69,79,70,32,114,101,97,100,32,119,104,101,114,101,32,110, + 111,116,32,101,120,112,101,99,116,101,100,115,4,0,0,0, + 80,75,1,2,233,8,0,0,0,233,10,0,0,0,233,14, + 0,0,0,233,24,0,0,0,233,28,0,0,0,233,30,0, + 0,0,233,32,0,0,0,233,34,0,0,0,233,42,0,0, + 0,122,25,98,97,100,32,108,111,99,97,108,32,104,101,97, + 100,101,114,32,111,102,102,115,101,116,58,32,105,0,8,0, + 0,218,5,97,115,99,105,105,90,6,108,97,116,105,110,49, + 250,1,47,114,5,0,0,0,122,33,122,105,112,105,109,112, + 111,114,116,58,32,102,111,117,110,100,32,123,125,32,110,97, + 109,101,115,32,105,110,32,123,33,114,125,41,26,218,3,95, + 105,111,218,9,111,112,101,110,95,99,111,100,101,114,22,0, + 0,0,114,3,0,0,0,218,4,115,101,101,107,218,20,69, + 78,68,95,67,69,78,84,82,65,76,95,68,73,82,95,83, + 73,90,69,90,4,116,101,108,108,218,4,114,101,97,100,114, + 51,0,0,0,218,18,83,84,82,73,78,71,95,69,78,68, + 95,65,82,67,72,73,86,69,218,3,109,97,120,218,15,77, + 65,88,95,67,79,77,77,69,78,84,95,76,69,78,218,5, + 114,102,105,110,100,114,2,0,0,0,218,8,69,79,70,69, + 114,114,111,114,114,1,0,0,0,114,62,0,0,0,218,18, + 85,110,105,99,111,100,101,68,101,99,111,100,101,69,114,114, + 111,114,218,9,116,114,97,110,115,108,97,116,101,218,11,99, + 112,52,51,55,95,116,97,98,108,101,114,19,0,0,0,114, + 20,0,0,0,114,21,0,0,0,114,30,0,0,0,114,76, + 0,0,0,114,77,0,0,0,41,26,114,29,0,0,0,218, + 2,102,112,90,15,104,101,97,100,101,114,95,112,111,115,105, + 116,105,111,110,218,6,98,117,102,102,101,114,218,9,102,105, + 108,101,95,115,105,122,101,90,17,109,97,120,95,99,111,109, + 109,101,110,116,95,115,116,97,114,116,218,4,100,97,116,97, + 90,3,112,111,115,218,11,104,101,97,100,101,114,95,115,105, + 122,101,90,13,104,101,97,100,101,114,95,111,102,102,115,101, + 116,90,10,97,114,99,95,111,102,102,115,101,116,114,33,0, + 0,0,218,5,99,111,117,110,116,218,5,102,108,97,103,115, + 218,8,99,111,109,112,114,101,115,115,218,4,116,105,109,101, + 218,4,100,97,116,101,218,3,99,114,99,218,9,100,97,116, + 97,95,115,105,122,101,218,9,110,97,109,101,95,115,105,122, + 101,218,10,101,120,116,114,97,95,115,105,122,101,90,12,99, + 111,109,109,101,110,116,95,115,105,122,101,218,11,102,105,108, + 101,95,111,102,102,115,101,116,114,59,0,0,0,114,13,0, + 0,0,218,1,116,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,27,0,0,0,93,1,0,0,115,212,0, + 0,0,0,1,2,1,14,1,12,1,24,2,8,1,2,1, + 14,1,8,1,14,1,12,1,24,1,12,1,18,1,18,3, + 2,1,12,1,12,1,12,1,10,1,2,255,12,2,8,1, + 2,255,2,1,2,255,4,2,2,1,10,1,12,1,14,1, + 10,1,2,255,12,2,10,1,10,1,10,1,2,255,6,2, + 16,1,14,1,10,1,2,255,6,2,16,2,16,1,16,1, + 10,1,18,1,10,1,18,1,8,1,8,1,10,1,18,2, + 4,2,4,1,2,1,14,1,14,1,24,2,10,1,14,1, + 8,2,18,1,4,1,14,1,8,1,16,1,16,1,16,1, + 16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1, + 12,1,10,1,18,1,8,2,2,1,14,1,14,1,24,1, + 14,1,18,4,2,1,28,1,22,1,14,1,24,2,10,2, + 10,3,2,1,14,1,14,1,22,2,12,1,12,1,20,1, + 8,1,44,1,14,1,114,27,0,0,0,117,190,1,0,0, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47, + 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, + 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, + 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, + 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, + 195,135,195,188,195,169,195,162,195,164,195,160,195,165,195,167, + 195,170,195,171,195,168,195,175,195,174,195,172,195,132,195,133, + 195,137,195,166,195,134,195,180,195,182,195,178,195,187,195,185, + 195,191,195,150,195,156,194,162,194,163,194,165,226,130,167,198, + 146,195,161,195,173,195,179,195,186,195,177,195,145,194,170,194, + 186,194,191,226,140,144,194,172,194,189,194,188,194,161,194,171, + 194,187,226,150,145,226,150,146,226,150,147,226,148,130,226,148, + 164,226,149,161,226,149,162,226,149,150,226,149,149,226,149,163, + 226,149,145,226,149,151,226,149,157,226,149,156,226,149,155,226, + 148,144,226,148,148,226,148,180,226,148,172,226,148,156,226,148, + 128,226,148,188,226,149,158,226,149,159,226,149,154,226,149,148, + 226,149,169,226,149,166,226,149,160,226,149,144,226,149,172,226, + 149,167,226,149,168,226,149,164,226,149,165,226,149,153,226,149, + 152,226,149,146,226,149,147,226,149,171,226,149,170,226,148,152, + 226,148,140,226,150,136,226,150,132,226,150,140,226,150,144,226, + 150,128,206,177,195,159,206,147,207,128,206,163,207,131,194,181, + 207,132,206,166,206,152,206,169,206,180,226,136,158,207,134,206, + 181,226,136,169,226,137,161,194,177,226,137,165,226,137,164,226, + 140,160,226,140,161,195,183,226,137,136,194,176,226,136,153,194, + 183,226,136,154,226,129,191,194,178,226,150,160,194,160,99,0, + 0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8, + 0,0,0,67,0,0,0,115,110,0,0,0,116,0,114,22, + 116,1,160,2,100,1,161,1,1,0,116,3,100,2,131,1, + 130,1,100,3,97,0,122,62,122,16,100,4,100,5,108,4, + 109,5,125,0,1,0,87,0,110,36,4,0,116,6,121,80, + 1,0,1,0,1,0,116,1,160,2,100,1,161,1,1,0, + 116,3,100,2,131,1,130,1,89,0,110,2,48,0,87,0, + 100,6,97,0,110,6,100,6,97,0,48,0,116,1,160,2, + 100,7,161,1,1,0,124,0,83,0,41,8,78,122,27,122, + 105,112,105,109,112,111,114,116,58,32,122,108,105,98,32,85, + 78,65,86,65,73,76,65,66,76,69,250,41,99,97,110,39, + 116,32,100,101,99,111,109,112,114,101,115,115,32,100,97,116, + 97,59,32,122,108,105,98,32,110,111,116,32,97,118,97,105, + 108,97,98,108,101,84,114,0,0,0,0,169,1,218,10,100, + 101,99,111,109,112,114,101,115,115,70,122,25,122,105,112,105, + 109,112,111,114,116,58,32,122,108,105,98,32,97,118,97,105, + 108,97,98,108,101,41,7,218,15,95,105,109,112,111,114,116, + 105,110,103,95,122,108,105,98,114,76,0,0,0,114,77,0, + 0,0,114,3,0,0,0,90,4,122,108,105,98,114,139,0, + 0,0,218,9,69,120,99,101,112,116,105,111,110,114,138,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,218,20,95,103,101,116,95,100,101,99,111,109,112,114,101, + 115,115,95,102,117,110,99,251,1,0,0,115,24,0,0,0, + 0,2,4,3,10,1,8,2,4,1,4,1,16,1,12,1, + 10,1,16,2,12,2,10,1,114,142,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,17,0,0,0,9,0, + 0,0,67,0,0,0,115,144,1,0,0,124,1,92,8,125, + 2,125,3,125,4,125,5,125,6,125,7,125,8,125,9,124, + 4,100,1,107,0,114,36,116,0,100,2,131,1,130,1,116, + 1,160,2,124,0,161,1,144,1,143,14,125,10,122,14,124, + 10,160,3,124,6,161,1,1,0,87,0,110,36,4,0,116, + 4,121,100,1,0,1,0,1,0,116,0,100,3,124,0,155, + 2,157,2,124,0,100,4,141,2,130,1,89,0,110,2,48, + 0,124,10,160,5,100,5,161,1,125,11,116,6,124,11,131, + 1,100,5,107,3,114,132,116,7,100,6,131,1,130,1,124, + 11,100,0,100,7,133,2,25,0,100,8,107,3,114,166,116, + 0,100,9,124,0,155,2,157,2,124,0,100,4,141,2,130, + 1,116,8,124,11,100,10,100,11,133,2,25,0,131,1,125, + 12,116,8,124,11,100,11,100,5,133,2,25,0,131,1,125, + 13,100,5,124,12,23,0,124,13,23,0,125,14,124,6,124, + 14,55,0,125,6,122,14,124,10,160,3,124,6,161,1,1, + 0,87,0,110,38,4,0,116,4,144,1,121,14,1,0,1, + 0,1,0,116,0,100,3,124,0,155,2,157,2,124,0,100, + 4,141,2,130,1,89,0,110,2,48,0,124,10,160,5,124, + 4,161,1,125,15,116,6,124,15,131,1,124,4,107,3,144, + 1,114,48,116,4,100,12,131,1,130,1,87,0,100,0,4, + 0,4,0,131,3,1,0,110,18,49,0,144,1,115,70,48, + 0,1,0,1,0,1,0,89,0,1,0,124,3,100,1,107, + 2,144,1,114,94,124,15,83,0,122,10,116,9,131,0,125, + 16,87,0,110,28,4,0,116,10,144,1,121,132,1,0,1, + 0,1,0,116,0,100,13,131,1,130,1,89,0,110,2,48, + 0,124,16,124,15,100,14,131,2,83,0,41,15,78,114,0, + 0,0,0,122,18,110,101,103,97,116,105,118,101,32,100,97, + 116,97,32,115,105,122,101,114,90,0,0,0,114,12,0,0, + 0,114,102,0,0,0,114,96,0,0,0,114,91,0,0,0, + 115,4,0,0,0,80,75,3,4,122,23,98,97,100,32,108, + 111,99,97,108,32,102,105,108,101,32,104,101,97,100,101,114, + 58,32,233,26,0,0,0,114,101,0,0,0,122,26,122,105, + 112,105,109,112,111,114,116,58,32,99,97,110,39,116,32,114, + 101,97,100,32,100,97,116,97,114,137,0,0,0,105,241,255, + 255,255,41,11,114,3,0,0,0,114,108,0,0,0,114,109, + 0,0,0,114,110,0,0,0,114,22,0,0,0,114,112,0, + 0,0,114,51,0,0,0,114,117,0,0,0,114,1,0,0, + 0,114,142,0,0,0,114,141,0,0,0,41,17,114,29,0, + 0,0,114,54,0,0,0,90,8,100,97,116,97,112,97,116, + 104,114,128,0,0,0,114,132,0,0,0,114,123,0,0,0, + 114,135,0,0,0,114,129,0,0,0,114,130,0,0,0,114, + 131,0,0,0,114,121,0,0,0,114,122,0,0,0,114,133, + 0,0,0,114,134,0,0,0,114,125,0,0,0,90,8,114, + 97,119,95,100,97,116,97,114,139,0,0,0,114,9,0,0, + 0,114,9,0,0,0,114,10,0,0,0,114,52,0,0,0, + 16,2,0,0,115,62,0,0,0,0,1,20,1,8,1,8, + 2,14,2,2,1,14,1,12,1,24,1,10,1,12,1,8, + 2,16,2,18,2,16,1,16,1,12,1,8,1,2,1,14, + 1,14,1,24,1,10,1,14,1,40,2,10,2,4,3,2, + 1,10,1,14,1,14,1,114,52,0,0,0,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, + 0,67,0,0,0,115,16,0,0,0,116,0,124,0,124,1, + 24,0,131,1,100,1,107,1,83,0,41,2,78,114,5,0, + 0,0,41,1,218,3,97,98,115,41,2,90,2,116,49,90, + 2,116,50,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,218,9,95,101,113,95,109,116,105,109,101,62,2,0, + 0,115,2,0,0,0,0,2,114,145,0,0,0,99,5,0, + 0,0,0,0,0,0,0,0,0,0,14,0,0,0,8,0, + 0,0,67,0,0,0,115,56,1,0,0,124,3,124,2,100, + 1,156,2,125,5,122,18,116,0,160,1,124,4,124,3,124, + 5,161,3,125,6,87,0,110,20,4,0,116,2,121,48,1, + 0,1,0,1,0,89,0,100,0,83,0,48,0,124,6,100, + 2,64,0,100,3,107,3,125,7,124,7,114,178,124,6,100, + 4,64,0,100,3,107,3,125,8,116,3,106,4,100,5,107, + 3,114,176,124,8,115,102,116,3,106,4,100,6,107,2,114, + 176,116,5,124,0,124,2,131,2,125,9,124,9,100,0,117, + 1,114,176,116,3,160,6,116,0,106,7,124,9,161,2,125, + 10,122,20,116,0,160,8,124,4,124,10,124,3,124,5,161, + 4,1,0,87,0,110,20,4,0,116,2,121,174,1,0,1, + 0,1,0,89,0,100,0,83,0,48,0,110,84,116,9,124, + 0,124,2,131,2,92,2,125,11,125,12,124,11,144,1,114, + 6,116,10,116,11,124,4,100,7,100,8,133,2,25,0,131, + 1,124,11,131,2,114,242,116,11,124,4,100,8,100,9,133, + 2,25,0,131,1,124,12,107,3,144,1,114,6,116,12,160, + 13,100,10,124,3,155,2,157,2,161,1,1,0,100,0,83, + 0,116,14,160,15,124,4,100,9,100,0,133,2,25,0,161, + 1,125,13,116,16,124,13,116,17,131,2,144,1,115,52,116, + 18,100,11,124,1,155,2,100,12,157,3,131,1,130,1,124, + 13,83,0,41,13,78,41,2,114,59,0,0,0,114,13,0, + 0,0,114,5,0,0,0,114,0,0,0,0,114,84,0,0, + 0,90,5,110,101,118,101,114,90,6,97,108,119,97,121,115, + 114,97,0,0,0,114,92,0,0,0,114,93,0,0,0,122, + 22,98,121,116,101,99,111,100,101,32,105,115,32,115,116,97, + 108,101,32,102,111,114,32,122,16,99,111,109,112,105,108,101, + 100,32,109,111,100,117,108,101,32,122,21,32,105,115,32,110, + 111,116,32,97,32,99,111,100,101,32,111,98,106,101,99,116, + 41,19,114,21,0,0,0,90,13,95,99,108,97,115,115,105, + 102,121,95,112,121,99,114,75,0,0,0,218,4,95,105,109, + 112,90,21,99,104,101,99,107,95,104,97,115,104,95,98,97, + 115,101,100,95,112,121,99,115,218,15,95,103,101,116,95,112, + 121,99,95,115,111,117,114,99,101,218,11,115,111,117,114,99, + 101,95,104,97,115,104,90,17,95,82,65,87,95,77,65,71, + 73,67,95,78,85,77,66,69,82,90,18,95,118,97,108,105, + 100,97,116,101,95,104,97,115,104,95,112,121,99,218,29,95, + 103,101,116,95,109,116,105,109,101,95,97,110,100,95,115,105, + 122,101,95,111,102,95,115,111,117,114,99,101,114,145,0,0, + 0,114,2,0,0,0,114,76,0,0,0,114,77,0,0,0, + 218,7,109,97,114,115,104,97,108,90,5,108,111,97,100,115, + 114,15,0,0,0,218,10,95,99,111,100,101,95,116,121,112, + 101,218,9,84,121,112,101,69,114,114,111,114,41,14,114,32, + 0,0,0,114,53,0,0,0,114,63,0,0,0,114,38,0, + 0,0,114,124,0,0,0,90,11,101,120,99,95,100,101,116, + 97,105,108,115,114,127,0,0,0,90,10,104,97,115,104,95, + 98,97,115,101,100,90,12,99,104,101,99,107,95,115,111,117, + 114,99,101,90,12,115,111,117,114,99,101,95,98,121,116,101, + 115,114,148,0,0,0,90,12,115,111,117,114,99,101,95,109, + 116,105,109,101,90,11,115,111,117,114,99,101,95,115,105,122, + 101,114,46,0,0,0,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,15,95,117,110,109,97,114,115,104,97, + 108,95,99,111,100,101,72,2,0,0,115,82,0,0,0,0, + 2,2,1,2,254,6,5,2,1,18,1,12,1,8,2,12, + 1,4,1,12,1,10,1,2,255,2,1,8,255,2,2,10, + 1,8,1,4,1,4,1,2,254,4,5,2,1,4,1,8, + 255,8,2,12,1,10,3,8,255,6,3,6,3,22,1,18, + 255,4,2,4,1,8,255,4,2,4,2,18,1,12,1,16, + 1,114,153,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,4,0,0,0,67,0,0,0,115, + 28,0,0,0,124,0,160,0,100,1,100,2,161,2,125,0, + 124,0,160,0,100,3,100,2,161,2,125,0,124,0,83,0, + 41,4,78,115,2,0,0,0,13,10,243,1,0,0,0,10, + 243,1,0,0,0,13,41,1,114,19,0,0,0,41,1,218, + 6,115,111,117,114,99,101,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,23,95,110,111,114,109,97,108,105, + 122,101,95,108,105,110,101,95,101,110,100,105,110,103,115,123, + 2,0,0,115,6,0,0,0,0,1,12,1,12,1,114,157, + 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,6,0,0,0,67,0,0,0,115,24,0,0, + 0,116,0,124,1,131,1,125,1,116,1,124,1,124,0,100, + 1,100,2,100,3,141,4,83,0,41,4,78,114,74,0,0, + 0,84,41,1,90,12,100,111,110,116,95,105,110,104,101,114, + 105,116,41,2,114,157,0,0,0,218,7,99,111,109,112,105, + 108,101,41,2,114,53,0,0,0,114,156,0,0,0,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,218,15,95, + 99,111,109,112,105,108,101,95,115,111,117,114,99,101,130,2, + 0,0,115,4,0,0,0,0,1,8,1,114,159,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,11,0,0,0,67,0,0,0,115,68,0,0,0,116,0, + 160,1,124,0,100,1,63,0,100,2,23,0,124,0,100,3, + 63,0,100,4,64,0,124,0,100,5,64,0,124,1,100,6, + 63,0,124,1,100,3,63,0,100,7,64,0,124,1,100,5, + 64,0,100,8,20,0,100,9,100,9,100,9,102,9,161,1, + 83,0,41,10,78,233,9,0,0,0,105,188,7,0,0,233, + 5,0,0,0,233,15,0,0,0,233,31,0,0,0,233,11, + 0,0,0,233,63,0,0,0,114,84,0,0,0,114,14,0, + 0,0,41,2,114,129,0,0,0,90,6,109,107,116,105,109, + 101,41,2,218,1,100,114,136,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,218,14,95,112,97,114, + 115,101,95,100,111,115,116,105,109,101,136,2,0,0,115,18, + 0,0,0,0,1,4,1,10,1,10,1,6,1,6,1,10, + 1,10,1,6,249,114,167,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,6,0,0,0,10,0,0,0,67, + 0,0,0,115,114,0,0,0,122,82,124,1,100,1,100,0, + 133,2,25,0,100,2,118,0,115,22,74,0,130,1,124,1, + 100,0,100,1,133,2,25,0,125,1,124,0,106,0,124,1, + 25,0,125,2,124,2,100,3,25,0,125,3,124,2,100,4, + 25,0,125,4,124,2,100,5,25,0,125,5,116,1,124,4, + 124,3,131,2,124,5,102,2,87,0,83,0,4,0,116,2, + 116,3,116,4,102,3,121,108,1,0,1,0,1,0,89,0, + 100,6,83,0,48,0,100,0,83,0,41,7,78,114,14,0, + 0,0,169,2,218,1,99,218,1,111,114,161,0,0,0,233, + 6,0,0,0,233,3,0,0,0,41,2,114,0,0,0,0, + 114,0,0,0,0,41,5,114,28,0,0,0,114,167,0,0, + 0,114,26,0,0,0,218,10,73,110,100,101,120,69,114,114, + 111,114,114,152,0,0,0,41,6,114,32,0,0,0,114,13, + 0,0,0,114,54,0,0,0,114,129,0,0,0,114,130,0, + 0,0,90,17,117,110,99,111,109,112,114,101,115,115,101,100, + 95,115,105,122,101,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,149,0,0,0,149,2,0,0,115,20,0, + 0,0,0,1,2,2,20,1,12,1,10,3,8,1,8,1, + 8,1,16,1,18,1,114,149,0,0,0,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,8,0,0,0, + 67,0,0,0,115,84,0,0,0,124,1,100,1,100,0,133, + 2,25,0,100,2,118,0,115,20,74,0,130,1,124,1,100, + 0,100,1,133,2,25,0,125,1,122,14,124,0,106,0,124, + 1,25,0,125,2,87,0,110,20,4,0,116,1,121,66,1, + 0,1,0,1,0,89,0,100,0,83,0,48,0,116,2,124, + 0,106,3,124,2,131,2,83,0,100,0,83,0,41,3,78, + 114,14,0,0,0,114,168,0,0,0,41,4,114,28,0,0, + 0,114,26,0,0,0,114,52,0,0,0,114,29,0,0,0, + 41,3,114,32,0,0,0,114,13,0,0,0,114,54,0,0, + 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 114,147,0,0,0,168,2,0,0,115,14,0,0,0,0,2, + 20,1,12,2,2,1,14,1,12,1,8,2,114,147,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,11,0, + 0,0,9,0,0,0,67,0,0,0,115,196,0,0,0,116, + 0,124,0,124,1,131,2,125,2,116,1,68,0,93,158,92, + 3,125,3,125,4,125,5,124,2,124,3,23,0,125,6,116, + 2,106,3,100,1,124,0,106,4,116,5,124,6,100,2,100, + 3,141,5,1,0,122,14,124,0,106,6,124,6,25,0,125, + 7,87,0,110,18,4,0,116,7,121,86,1,0,1,0,1, + 0,89,0,113,14,48,0,124,7,100,4,25,0,125,8,116, + 8,124,0,106,4,124,7,131,2,125,9,124,4,114,130,116, + 9,124,0,124,8,124,6,124,1,124,9,131,5,125,10,110, + 10,116,10,124,8,124,9,131,2,125,10,124,10,100,0,117, + 0,114,150,113,14,124,7,100,4,25,0,125,8,124,10,124, + 5,124,8,102,3,2,0,1,0,83,0,113,14,116,11,100, + 5,124,1,155,2,157,2,124,1,100,6,141,2,130,1,100, + 0,83,0,41,7,78,122,13,116,114,121,105,110,103,32,123, + 125,123,125,123,125,114,84,0,0,0,41,1,90,9,118,101, + 114,98,111,115,105,116,121,114,0,0,0,0,114,57,0,0, + 0,114,58,0,0,0,41,12,114,36,0,0,0,114,87,0, + 0,0,114,76,0,0,0,114,77,0,0,0,114,29,0,0, + 0,114,20,0,0,0,114,28,0,0,0,114,26,0,0,0, + 114,52,0,0,0,114,153,0,0,0,114,159,0,0,0,114, + 3,0,0,0,41,11,114,32,0,0,0,114,38,0,0,0, + 114,13,0,0,0,114,88,0,0,0,114,89,0,0,0,114, + 47,0,0,0,114,63,0,0,0,114,54,0,0,0,114,40, + 0,0,0,114,124,0,0,0,114,46,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,44,0,0, + 0,183,2,0,0,115,36,0,0,0,0,1,10,1,14,1, + 8,1,22,1,2,1,14,1,12,1,6,2,8,1,12,1, + 4,1,18,2,10,1,8,3,2,1,8,1,16,2,114,44, + 0,0,0,41,44,114,82,0,0,0,90,26,95,102,114,111, + 122,101,110,95,105,109,112,111,114,116,108,105,98,95,101,120, + 116,101,114,110,97,108,114,21,0,0,0,114,1,0,0,0, + 114,2,0,0,0,90,17,95,102,114,111,122,101,110,95,105, + 109,112,111,114,116,108,105,98,114,76,0,0,0,114,146,0, + 0,0,114,108,0,0,0,114,150,0,0,0,114,67,0,0, + 0,114,129,0,0,0,90,7,95,95,97,108,108,95,95,114, + 20,0,0,0,90,15,112,97,116,104,95,115,101,112,97,114, + 97,116,111,114,115,114,18,0,0,0,114,75,0,0,0,114, + 3,0,0,0,114,25,0,0,0,218,4,116,121,112,101,114, + 70,0,0,0,114,111,0,0,0,114,113,0,0,0,114,115, + 0,0,0,114,4,0,0,0,114,87,0,0,0,114,36,0, + 0,0,114,37,0,0,0,114,35,0,0,0,114,27,0,0, + 0,114,120,0,0,0,114,140,0,0,0,114,142,0,0,0, + 114,52,0,0,0,114,145,0,0,0,114,153,0,0,0,218, + 8,95,95,99,111,100,101,95,95,114,151,0,0,0,114,157, + 0,0,0,114,159,0,0,0,114,167,0,0,0,114,149,0, + 0,0,114,147,0,0,0,114,44,0,0,0,114,9,0,0, 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,13,114,101,115,111,117,114,99,101,95,112,97,116,104,233, - 2,0,0,115,2,0,0,0,0,4,122,38,95,90,105,112, - 73,109,112,111,114,116,82,101,115,111,117,114,99,101,82,101, - 97,100,101,114,46,114,101,115,111,117,114,99,101,95,112,97, - 116,104,99,2,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,8,0,0,0,67,0,0,0,115,70,0,0,0, - 124,0,106,0,160,1,100,1,100,2,161,2,125,2,124,2, - 155,0,100,2,124,1,155,0,157,3,125,3,122,16,124,0, - 106,2,160,3,124,3,161,1,1,0,87,0,110,20,4,0, - 116,4,121,64,1,0,1,0,1,0,89,0,100,3,83,0, - 48,0,100,4,83,0,41,5,78,114,85,0,0,0,114,109, - 0,0,0,70,84,41,5,114,38,0,0,0,114,19,0,0, - 0,114,4,0,0,0,114,55,0,0,0,114,22,0,0,0, - 41,4,114,32,0,0,0,114,59,0,0,0,114,179,0,0, - 0,114,13,0,0,0,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,11,105,115,95,114,101,115,111,117,114, - 99,101,239,2,0,0,115,14,0,0,0,0,3,14,1,14, - 1,2,1,16,1,12,1,8,1,122,36,95,90,105,112,73, - 109,112,111,114,116,82,101,115,111,117,114,99,101,82,101,97, - 100,101,114,46,105,115,95,114,101,115,111,117,114,99,101,99, - 1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0, - 9,0,0,0,99,0,0,0,115,184,0,0,0,100,1,100, - 2,108,0,109,1,125,1,1,0,124,1,124,0,106,2,160, - 3,124,0,106,4,161,1,131,1,125,2,124,2,160,5,124, - 0,106,2,106,6,161,1,125,3,124,3,106,7,100,3,107, - 2,115,58,74,0,130,1,124,3,106,8,125,4,116,9,131, - 0,125,5,124,0,106,2,106,10,68,0,93,100,125,6,122, - 18,124,1,124,6,131,1,160,5,124,4,161,1,125,7,87, - 0,110,22,4,0,116,11,121,122,1,0,1,0,1,0,89, - 0,113,78,89,0,110,2,48,0,124,7,106,8,106,7,125, - 8,116,12,124,8,131,1,100,1,107,2,114,154,124,7,106, - 7,86,0,1,0,113,78,124,8,124,5,118,1,114,78,124, - 5,160,13,124,8,161,1,1,0,124,8,86,0,1,0,113, - 78,100,0,83,0,41,4,78,114,0,0,0,0,41,1,218, - 4,80,97,116,104,114,60,0,0,0,41,14,90,7,112,97, - 116,104,108,105,98,114,183,0,0,0,114,4,0,0,0,114, - 56,0,0,0,114,38,0,0,0,90,11,114,101,108,97,116, - 105,118,101,95,116,111,114,29,0,0,0,114,59,0,0,0, - 90,6,112,97,114,101,110,116,218,3,115,101,116,114,28,0, - 0,0,114,23,0,0,0,114,51,0,0,0,218,3,97,100, - 100,41,9,114,32,0,0,0,114,183,0,0,0,90,13,102, - 117,108,108,110,97,109,101,95,112,97,116,104,90,13,114,101, - 108,97,116,105,118,101,95,112,97,116,104,90,12,112,97,99, - 107,97,103,101,95,112,97,116,104,90,12,115,117,98,100,105, - 114,115,95,115,101,101,110,218,8,102,105,108,101,110,97,109, - 101,90,8,114,101,108,97,116,105,118,101,90,11,112,97,114, - 101,110,116,95,110,97,109,101,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,8,99,111,110,116,101,110,116, - 115,250,2,0,0,115,34,0,0,0,0,8,12,1,18,1, - 14,3,14,1,6,1,6,1,12,1,2,1,18,1,12,1, - 10,5,8,1,12,1,10,1,8,1,10,1,122,33,95,90, - 105,112,73,109,112,111,114,116,82,101,115,111,117,114,99,101, - 82,101,97,100,101,114,46,99,111,110,116,101,110,116,115,78, - 41,10,114,6,0,0,0,114,7,0,0,0,114,8,0,0, - 0,114,84,0,0,0,114,81,0,0,0,114,34,0,0,0, - 114,180,0,0,0,114,181,0,0,0,114,182,0,0,0,114, - 187,0,0,0,114,9,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,80,0,0,0,212,2,0, - 0,115,14,0,0,0,8,1,4,5,4,2,8,4,8,9, - 8,6,8,11,114,80,0,0,0,41,45,114,84,0,0,0, - 90,26,95,102,114,111,122,101,110,95,105,109,112,111,114,116, - 108,105,98,95,101,120,116,101,114,110,97,108,114,21,0,0, - 0,114,1,0,0,0,114,2,0,0,0,90,17,95,102,114, - 111,122,101,110,95,105,109,112,111,114,116,108,105,98,114,76, - 0,0,0,114,148,0,0,0,114,110,0,0,0,114,152,0, - 0,0,114,67,0,0,0,114,131,0,0,0,90,7,95,95, - 97,108,108,95,95,114,20,0,0,0,90,15,112,97,116,104, - 95,115,101,112,97,114,97,116,111,114,115,114,18,0,0,0, - 114,75,0,0,0,114,3,0,0,0,114,25,0,0,0,218, - 4,116,121,112,101,114,70,0,0,0,114,113,0,0,0,114, - 115,0,0,0,114,117,0,0,0,114,4,0,0,0,114,89, - 0,0,0,114,36,0,0,0,114,37,0,0,0,114,35,0, - 0,0,114,27,0,0,0,114,122,0,0,0,114,142,0,0, - 0,114,144,0,0,0,114,52,0,0,0,114,147,0,0,0, - 114,155,0,0,0,218,8,95,95,99,111,100,101,95,95,114, - 153,0,0,0,114,159,0,0,0,114,161,0,0,0,114,169, - 0,0,0,114,151,0,0,0,114,149,0,0,0,114,44,0, - 0,0,114,80,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,8,60,109,111, - 100,117,108,101,62,1,0,0,0,115,88,0,0,0,4,16, - 8,1,16,1,8,1,8,1,8,1,8,1,8,1,8,2, - 8,3,6,1,14,3,16,4,4,2,8,2,4,1,4,1, - 4,2,14,127,0,127,0,1,12,1,12,1,2,1,2,252, - 4,9,8,4,8,9,8,31,8,126,2,254,2,29,4,5, - 8,21,8,46,8,10,8,46,10,5,8,7,8,6,8,13, - 8,19,8,15,8,26, + 218,8,60,109,111,100,117,108,101,62,1,0,0,0,115,84, + 0,0,0,4,16,8,1,16,1,8,1,8,1,8,1,8, + 1,8,1,8,2,8,3,6,1,14,3,16,4,4,2,8, + 2,4,1,4,1,4,2,14,127,0,125,12,1,12,1,2, + 1,2,252,4,9,8,4,8,9,8,31,8,126,2,254,2, + 29,4,5,8,21,8,46,8,10,8,46,10,5,8,7,8, + 6,8,13,8,19,8,15, }; From webhook-mailer at python.org Sun Jun 7 21:57:07 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Mon, 08 Jun 2020 01:57:07 -0000 Subject: [Python-checkins] bpo-40903: Handle multiple '=' in invalid assignment rules in the PEG parser (GH-20697) Message-ID: https://github.com/python/cpython/commit/9f495908c5bd3645ed1af82d7bae6782720dab77 commit: 9f495908c5bd3645ed1af82d7bae6782720dab77 branch: master author: Pablo Galindo committer: GitHub date: 2020-06-07T18:57:00-07:00 summary: bpo-40903: Handle multiple '=' in invalid assignment rules in the PEG parser (GH-20697) Automerge-Triggered-By: @pablogsal files: A Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst M Grammar/python.gram M Lib/test/test_syntax.py M Parser/pegen/parse.c M Parser/pegen/pegen.c diff --git a/Grammar/python.gram b/Grammar/python.gram index 19d9bb36fed5f..dd425eff30b7d 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -92,7 +92,7 @@ assignment[stmt_ty]: | a=('(' b=single_target ')' { b } | single_subscript_attribute_target) ':' b=expression c=['=' d=annotated_rhs { d }] { CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) } - | a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) tc=[TYPE_COMMENT] { + | a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) !'=' tc=[TYPE_COMMENT] { _Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) } | a=single_target b=augassign c=(yield_expr | star_expressions) { _Py_AugAssign(a, b->kind, c, EXTRA) } @@ -646,10 +646,11 @@ invalid_assignment: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "only single target (not tuple) can be annotated") } | a=expression ':' expression ['=' annotated_rhs] { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") } - | a=star_expressions '=' (yield_expr | star_expressions) { + | (star_targets '=')* a=star_expressions '=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION( _PyPegen_get_invalid_target(a), "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target(a))) } + | (star_targets '=')* a=yield_expr '=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "assignment to yield expression not possible") } | a=star_expressions augassign (yield_expr | star_expressions) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION( a, diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 4df5535b0053b..f41426a4e9d2d 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -63,6 +63,10 @@ Traceback (most recent call last): SyntaxError: cannot assign to function call +>>> yield = 1 +Traceback (most recent call last): +SyntaxError: assignment to yield expression not possible + >>> del f() Traceback (most recent call last): SyntaxError: cannot delete function call @@ -136,6 +140,18 @@ Traceback (most recent call last): SyntaxError: cannot assign to conditional expression +>>> True = True = 3 +Traceback (most recent call last): +SyntaxError: cannot assign to True + +>>> x = y = True = z = 3 +Traceback (most recent call last): +SyntaxError: cannot assign to True + +>>> x = y = yield = 1 +Traceback (most recent call last): +SyntaxError: assignment to yield expression not possible + >>> a, b += 1, 2 Traceback (most recent call last): SyntaxError: 'tuple' is an illegal expression for augmented assignment @@ -148,6 +164,10 @@ Traceback (most recent call last): SyntaxError: 'list' is an illegal expression for augmented assignment +>>> p = p = +Traceback (most recent call last): +SyntaxError: invalid syntax + From compiler_complex_args(): >>> def f(None=1): @@ -155,7 +175,6 @@ Traceback (most recent call last): SyntaxError: invalid syntax - From ast_for_arguments(): >>> def f(x, y=1, z): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst new file mode 100644 index 0000000000000..5ee72c14ad352 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-07-22-50-10.bpo-40903.7dWejS.rst @@ -0,0 +1 @@ +Fixed a possible segfault in the new PEG parser when producing error messages for invalid assignments of the form :code:`p=p=`. Patch by Pablo Galindo \ No newline at end of file diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index b63924177d400..e5738e3e04afe 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -358,11 +358,11 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_125_type 1280 #define _loop0_126_type 1281 #define _tmp_127_type 1282 -#define _tmp_128_type 1283 -#define _tmp_129_type 1284 +#define _loop0_128_type 1283 +#define _loop0_129_type 1284 #define _tmp_130_type 1285 -#define _loop0_131_type 1286 -#define _tmp_132_type 1287 +#define _tmp_131_type 1286 +#define _loop0_132_type 1287 #define _tmp_133_type 1288 #define _tmp_134_type 1289 #define _tmp_135_type 1290 @@ -376,9 +376,12 @@ static KeywordToken *reserved_keywords[] = { #define _tmp_143_type 1298 #define _tmp_144_type 1299 #define _tmp_145_type 1300 -#define _loop1_146_type 1301 +#define _tmp_146_type 1301 #define _tmp_147_type 1302 #define _tmp_148_type 1303 +#define _loop1_149_type 1304 +#define _tmp_150_type 1305 +#define _tmp_151_type 1306 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -663,11 +666,11 @@ static asdl_seq *_gather_123_rule(Parser *p); static void *_tmp_125_rule(Parser *p); static asdl_seq *_loop0_126_rule(Parser *p); static void *_tmp_127_rule(Parser *p); -static void *_tmp_128_rule(Parser *p); -static void *_tmp_129_rule(Parser *p); +static asdl_seq *_loop0_128_rule(Parser *p); +static asdl_seq *_loop0_129_rule(Parser *p); static void *_tmp_130_rule(Parser *p); -static asdl_seq *_loop0_131_rule(Parser *p); -static void *_tmp_132_rule(Parser *p); +static void *_tmp_131_rule(Parser *p); +static asdl_seq *_loop0_132_rule(Parser *p); static void *_tmp_133_rule(Parser *p); static void *_tmp_134_rule(Parser *p); static void *_tmp_135_rule(Parser *p); @@ -681,9 +684,12 @@ static void *_tmp_142_rule(Parser *p); static void *_tmp_143_rule(Parser *p); static void *_tmp_144_rule(Parser *p); static void *_tmp_145_rule(Parser *p); -static asdl_seq *_loop1_146_rule(Parser *p); +static void *_tmp_146_rule(Parser *p); static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); +static asdl_seq *_loop1_149_rule(Parser *p); +static void *_tmp_150_rule(Parser *p); +static void *_tmp_151_rule(Parser *p); // file: statements? $ @@ -1998,7 +2004,7 @@ compound_stmt_rule(Parser *p) // assignment: // | NAME ':' expression ['=' annotated_rhs] // | ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs] -// | ((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT? +// | ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? // | single_target augassign (yield_expr | star_expressions) // | invalid_assignment static stmt_ty @@ -2104,12 +2110,12 @@ assignment_rule(Parser *p) D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); } - { // ((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT? + { // ((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT? if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT?")); + D(fprintf(stderr, "%*c> assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); asdl_seq * a; void *b; void *tc; @@ -2118,10 +2124,12 @@ assignment_rule(Parser *p) && (b = _tmp_23_rule(p)) // yield_expr | star_expressions && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' + && (tc = _PyPegen_expect_token(p, TYPE_COMMENT), 1) // TYPE_COMMENT? ) { - D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT?")); + D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { D(p->level--); @@ -2141,7 +2149,7 @@ assignment_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))+ (yield_expr | star_expressions) !'=' TYPE_COMMENT?")); } { // single_target augassign (yield_expr | star_expressions) if (p->error_indicator) { @@ -14568,7 +14576,8 @@ invalid_named_expression_rule(Parser *p) // | tuple ':' // | star_named_expression ',' star_named_expressions* ':' // | expression ':' expression ['=' annotated_rhs] -// | star_expressions '=' (yield_expr | star_expressions) +// | ((star_targets '='))* star_expressions '=' +// | ((star_targets '='))* yield_expr '=' // | star_expressions augassign (yield_expr | star_expressions) static void * invalid_assignment_rule(Parser *p) @@ -14701,24 +14710,24 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ':' expression ['=' annotated_rhs]")); } - { // star_expressions '=' (yield_expr | star_expressions) + { // ((star_targets '='))* star_expressions '=' if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions '=' (yield_expr | star_expressions)")); + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - void *_tmp_128_var; + asdl_seq * _loop0_128_var; expr_ty a; if ( + (_loop0_128_var = _loop0_128_rule(p)) // ((star_targets '='))* + && (a = star_expressions_rule(p)) // star_expressions && (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (_tmp_128_var = _tmp_128_rule(p)) // yield_expr | star_expressions ) { - D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions '=' (yield_expr | star_expressions)")); + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( _PyPegen_get_invalid_target ( a ) , "cannot assign to %s" , _PyPegen_get_expr_name ( _PyPegen_get_invalid_target ( a ) ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -14729,7 +14738,37 @@ invalid_assignment_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions '=' (yield_expr | star_expressions)")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* star_expressions '='")); + } + { // ((star_targets '='))* yield_expr '=' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); + Token * _literal; + asdl_seq * _loop0_129_var; + expr_ty a; + if ( + (_loop0_129_var = _loop0_129_rule(p)) // ((star_targets '='))* + && + (a = yield_expr_rule(p)) // yield_expr + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "assignment to yield expression not possible" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_assignment[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((star_targets '='))* yield_expr '='")); } { // star_expressions augassign (yield_expr | star_expressions) if (p->error_indicator) { @@ -14737,7 +14776,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_129_var; + void *_tmp_130_var; expr_ty a; AugOperator* augassign_var; if ( @@ -14745,7 +14784,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions + (_tmp_130_var = _tmp_130_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -14827,11 +14866,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_130_var; + void *_tmp_131_var; expr_ty a; asdl_seq* for_if_clauses_var; if ( - (_tmp_130_var = _tmp_130_rule(p)) // '[' | '(' | '{' + (_tmp_131_var = _tmp_131_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -14928,13 +14967,13 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* (slash_with_default | param_with_default+) param_no_default")); - asdl_seq * _loop0_131_var; - void *_tmp_132_var; + asdl_seq * _loop0_132_var; + void *_tmp_133_var; arg_ty param_no_default_var; if ( - (_loop0_131_var = _loop0_131_rule(p)) // param_no_default* + (_loop0_132_var = _loop0_132_rule(p)) // param_no_default* && - (_tmp_132_var = _tmp_132_rule(p)) // slash_with_default | param_with_default+ + (_tmp_133_var = _tmp_133_rule(p)) // slash_with_default | param_with_default+ && (param_no_default_var = param_no_default_rule(p)) // param_no_default ) @@ -14976,11 +15015,11 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); Token * _literal; - void *_tmp_133_var; + void *_tmp_134_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_133_var = _tmp_133_rule(p)) // ')' | ',' (')' | '**') + (_tmp_134_var = _tmp_134_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -15050,11 +15089,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_134_var; + void *_tmp_135_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_134_var = _tmp_134_rule(p)) // ':' | ',' (':' | '**') + (_tmp_135_var = _tmp_135_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -16464,12 +16503,12 @@ _loop1_22_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_135_var; + void *_tmp_136_var; while ( - (_tmp_135_var = _tmp_135_rule(p)) // star_targets '=' + (_tmp_136_var = _tmp_136_rule(p)) // star_targets '=' ) { - _res = _tmp_135_var; + _res = _tmp_136_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16917,12 +16956,12 @@ _loop0_30_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_136_var; + void *_tmp_137_var; while ( - (_tmp_136_var = _tmp_136_rule(p)) // '.' | '...' + (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' ) { - _res = _tmp_136_var; + _res = _tmp_137_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16983,12 +17022,12 @@ _loop1_31_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_137_var; + void *_tmp_138_var; while ( - (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' + (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...' ) { - _res = _tmp_137_var; + _res = _tmp_138_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19115,12 +19154,12 @@ _loop1_67_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_138_var; + void *_tmp_139_var; while ( - (_tmp_138_var = _tmp_138_rule(p)) // '@' named_expression NEWLINE + (_tmp_139_var = _tmp_139_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_138_var; + _res = _tmp_139_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19347,12 +19386,12 @@ _loop1_71_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_139_var; + void *_tmp_140_var; while ( - (_tmp_139_var = _tmp_139_rule(p)) // ',' star_expression + (_tmp_140_var = _tmp_140_rule(p)) // ',' star_expression ) { - _res = _tmp_139_var; + _res = _tmp_140_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19532,12 +19571,12 @@ _loop1_74_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_140_var; + void *_tmp_141_var; while ( - (_tmp_140_var = _tmp_140_rule(p)) // ',' expression + (_tmp_141_var = _tmp_141_rule(p)) // ',' expression ) { - _res = _tmp_140_var; + _res = _tmp_141_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -20562,12 +20601,12 @@ _loop1_89_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_141_var; + void *_tmp_142_var; while ( - (_tmp_141_var = _tmp_141_rule(p)) // 'or' conjunction + (_tmp_142_var = _tmp_142_rule(p)) // 'or' conjunction ) { - _res = _tmp_141_var; + _res = _tmp_142_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -20633,12 +20672,12 @@ _loop1_90_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_142_var; + void *_tmp_143_var; while ( - (_tmp_142_var = _tmp_142_rule(p)) // 'and' inversion + (_tmp_143_var = _tmp_143_rule(p)) // 'and' inversion ) { - _res = _tmp_142_var; + _res = _tmp_143_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21554,12 +21593,12 @@ _loop0_105_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_143_var; + void *_tmp_144_var; while ( - (_tmp_143_var = _tmp_143_rule(p)) // 'if' disjunction + (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction ) { - _res = _tmp_143_var; + _res = _tmp_144_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21620,12 +21659,12 @@ _loop0_106_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_144_var; + void *_tmp_145_var; while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction + (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction ) { - _res = _tmp_144_var; + _res = _tmp_145_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22230,12 +22269,12 @@ _loop0_117_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_145_var; + void *_tmp_146_var; while ( - (_tmp_145_var = _tmp_145_rule(p)) // ',' star_target + (_tmp_146_var = _tmp_146_rule(p)) // ',' star_target ) { - _res = _tmp_145_var; + _res = _tmp_146_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22812,64 +22851,141 @@ _tmp_127_rule(Parser *p) return _res; } -// _tmp_128: yield_expr | star_expressions -static void * -_tmp_128_rule(Parser *p) +// _loop0_128: (star_targets '=') +static asdl_seq * +_loop0_128_rule(Parser *p) { D(p->level++); if (p->error_indicator) { D(p->level--); return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // yield_expr + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + ssize_t _children_capacity = 1; + ssize_t _n = 0; + { // (star_targets '=') if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; - if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr + D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_147_var; + while ( + (_tmp_147_var = _tmp_147_rule(p)) // star_targets '=' ) { - D(fprintf(stderr, "%*c+ _tmp_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; - goto done; + _res = _tmp_147_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_128[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } - { // star_expressions + asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); + D(p->level--); + return _seq; +} + +// _loop0_129: (star_targets '=') +static asdl_seq * +_loop0_129_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + ssize_t _children_capacity = 1; + ssize_t _n = 0; + { // (star_targets '=') if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; - if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions + D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_148_var; + while ( + (_tmp_148_var = _tmp_148_rule(p)) // star_targets '=' ) { - D(fprintf(stderr, "%*c+ _tmp_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; - goto done; + _res = _tmp_148_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_128[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } - _res = NULL; - done: + asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq); D(p->level--); - return _res; + return _seq; } -// _tmp_129: yield_expr | star_expressions +// _tmp_130: yield_expr | star_expressions static void * -_tmp_129_rule(Parser *p) +_tmp_130_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22883,18 +22999,18 @@ _tmp_129_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_129[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -22902,18 +23018,18 @@ _tmp_129_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_129[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -22922,9 +23038,9 @@ _tmp_129_rule(Parser *p) return _res; } -// _tmp_130: '[' | '(' | '{' +// _tmp_131: '[' | '(' | '{' static void * -_tmp_130_rule(Parser *p) +_tmp_131_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -22938,18 +23054,18 @@ _tmp_130_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -22957,18 +23073,18 @@ _tmp_130_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -22976,18 +23092,18 @@ _tmp_130_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -22996,9 +23112,9 @@ _tmp_130_rule(Parser *p) return _res; } -// _loop0_131: param_no_default +// _loop0_132: param_no_default static asdl_seq * -_loop0_131_rule(Parser *p) +_loop0_132_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23022,7 +23138,7 @@ _loop0_131_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -23044,7 +23160,7 @@ _loop0_131_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); @@ -23057,14 +23173,14 @@ _loop0_131_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_131_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_132_type, _seq); D(p->level--); return _seq; } -// _tmp_132: slash_with_default | param_with_default+ +// _tmp_133: slash_with_default | param_with_default+ static void * -_tmp_132_rule(Parser *p) +_tmp_133_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23078,18 +23194,18 @@ _tmp_132_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } { // param_with_default+ @@ -23097,18 +23213,18 @@ _tmp_132_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_146_var; + D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + asdl_seq * _loop1_149_var; if ( - (_loop1_146_var = _loop1_146_rule(p)) // param_with_default+ + (_loop1_149_var = _loop1_149_rule(p)) // param_with_default+ ) { - D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_146_var; + D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); + _res = _loop1_149_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default+")); } _res = NULL; @@ -23117,9 +23233,9 @@ _tmp_132_rule(Parser *p) return _res; } -// _tmp_133: ')' | ',' (')' | '**') +// _tmp_134: ')' | ',' (')' | '**') static void * -_tmp_133_rule(Parser *p) +_tmp_134_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23133,18 +23249,18 @@ _tmp_133_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -23152,21 +23268,21 @@ _tmp_133_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_147_var; + void *_tmp_150_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_147_var = _tmp_147_rule(p)) // ')' | '**' + (_tmp_150_var = _tmp_150_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_147_var); + D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_150_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -23175,9 +23291,9 @@ _tmp_133_rule(Parser *p) return _res; } -// _tmp_134: ':' | ',' (':' | '**') +// _tmp_135: ':' | ',' (':' | '**') static void * -_tmp_134_rule(Parser *p) +_tmp_135_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23191,18 +23307,18 @@ _tmp_134_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -23210,21 +23326,21 @@ _tmp_134_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_148_var; + void *_tmp_151_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_148_var = _tmp_148_rule(p)) // ':' | '**' + (_tmp_151_var = _tmp_151_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_148_var); + D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_151_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -23233,9 +23349,9 @@ _tmp_134_rule(Parser *p) return _res; } -// _tmp_135: star_targets '=' +// _tmp_136: star_targets '=' static void * -_tmp_135_rule(Parser *p) +_tmp_136_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23249,7 +23365,7 @@ _tmp_135_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -23258,7 +23374,7 @@ _tmp_135_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23268,7 +23384,7 @@ _tmp_135_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -23277,9 +23393,9 @@ _tmp_135_rule(Parser *p) return _res; } -// _tmp_136: '.' | '...' +// _tmp_137: '.' | '...' static void * -_tmp_136_rule(Parser *p) +_tmp_137_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23293,18 +23409,18 @@ _tmp_136_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23312,18 +23428,18 @@ _tmp_136_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -23332,9 +23448,9 @@ _tmp_136_rule(Parser *p) return _res; } -// _tmp_137: '.' | '...' +// _tmp_138: '.' | '...' static void * -_tmp_137_rule(Parser *p) +_tmp_138_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23348,18 +23464,18 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23367,18 +23483,18 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -23387,9 +23503,9 @@ _tmp_137_rule(Parser *p) return _res; } -// _tmp_138: '@' named_expression NEWLINE +// _tmp_139: '@' named_expression NEWLINE static void * -_tmp_138_rule(Parser *p) +_tmp_139_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23403,7 +23519,7 @@ _tmp_138_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -23415,7 +23531,7 @@ _tmp_138_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23425,7 +23541,7 @@ _tmp_138_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -23434,9 +23550,9 @@ _tmp_138_rule(Parser *p) return _res; } -// _tmp_139: ',' star_expression +// _tmp_140: ',' star_expression static void * -_tmp_139_rule(Parser *p) +_tmp_140_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23450,7 +23566,7 @@ _tmp_139_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -23459,7 +23575,7 @@ _tmp_139_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23469,7 +23585,7 @@ _tmp_139_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -23478,9 +23594,9 @@ _tmp_139_rule(Parser *p) return _res; } -// _tmp_140: ',' expression +// _tmp_141: ',' expression static void * -_tmp_140_rule(Parser *p) +_tmp_141_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23494,7 +23610,7 @@ _tmp_140_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -23503,7 +23619,7 @@ _tmp_140_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23513,7 +23629,7 @@ _tmp_140_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -23522,9 +23638,9 @@ _tmp_140_rule(Parser *p) return _res; } -// _tmp_141: 'or' conjunction +// _tmp_142: 'or' conjunction static void * -_tmp_141_rule(Parser *p) +_tmp_142_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23538,7 +23654,7 @@ _tmp_141_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -23547,7 +23663,7 @@ _tmp_141_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23557,7 +23673,7 @@ _tmp_141_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -23566,9 +23682,9 @@ _tmp_141_rule(Parser *p) return _res; } -// _tmp_142: 'and' inversion +// _tmp_143: 'and' inversion static void * -_tmp_142_rule(Parser *p) +_tmp_143_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23582,7 +23698,7 @@ _tmp_142_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -23591,7 +23707,7 @@ _tmp_142_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23601,7 +23717,7 @@ _tmp_142_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -23610,9 +23726,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: 'if' disjunction +// _tmp_144: 'if' disjunction static void * -_tmp_143_rule(Parser *p) +_tmp_144_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23626,7 +23742,7 @@ _tmp_143_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -23635,7 +23751,7 @@ _tmp_143_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23645,7 +23761,7 @@ _tmp_143_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -23654,9 +23770,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'if' disjunction +// _tmp_145: 'if' disjunction static void * -_tmp_144_rule(Parser *p) +_tmp_145_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23670,7 +23786,7 @@ _tmp_144_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -23679,7 +23795,7 @@ _tmp_144_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23689,7 +23805,7 @@ _tmp_144_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -23698,9 +23814,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: ',' star_target +// _tmp_146: ',' star_target static void * -_tmp_145_rule(Parser *p) +_tmp_146_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23714,7 +23830,7 @@ _tmp_145_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -23723,7 +23839,7 @@ _tmp_145_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23733,7 +23849,7 @@ _tmp_145_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -23742,9 +23858,87 @@ _tmp_145_rule(Parser *p) return _res; } -// _loop1_146: param_with_default +// _tmp_147: star_targets '=' +static void * +_tmp_147_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // star_targets '=' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + +// _tmp_148: star_targets '=' +static void * +_tmp_148_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // star_targets '=' + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + Token * _literal; + expr_ty star_targets_var; + if ( + (star_targets_var = star_targets_rule(p)) // star_targets + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + _res = _PyPegen_dummy_name(p, star_targets_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + +// _loop1_149: param_with_default static asdl_seq * -_loop1_146_rule(Parser *p) +_loop1_149_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23768,7 +23962,7 @@ _loop1_146_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop1_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -23790,7 +23984,7 @@ _loop1_146_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_146[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_149[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -23808,14 +24002,14 @@ _loop1_146_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_146_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_149_type, _seq); D(p->level--); return _seq; } -// _tmp_147: ')' | '**' +// _tmp_150: ')' | '**' static void * -_tmp_147_rule(Parser *p) +_tmp_150_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23829,18 +24023,18 @@ _tmp_147_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -23848,18 +24042,18 @@ _tmp_147_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -23868,9 +24062,9 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: ':' | '**' +// _tmp_151: ':' | '**' static void * -_tmp_148_rule(Parser *p) +_tmp_151_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23884,18 +24078,18 @@ _tmp_148_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -23903,18 +24097,18 @@ _tmp_148_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c index afe75d7f862ee..7b581cadfb64a 100644 --- a/Parser/pegen/pegen.c +++ b/Parser/pegen/pegen.c @@ -161,6 +161,7 @@ byte_offset_to_character_offset(PyObject *line, int col_offset) const char * _PyPegen_get_expr_name(expr_ty e) { + assert(e != NULL); switch (e->kind) { case Attribute_kind: return "attribute"; From webhook-mailer at python.org Sun Jun 7 22:24:42 2020 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 08 Jun 2020 02:24:42 -0000 Subject: [Python-checkins] bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) Message-ID: https://github.com/python/cpython/commit/37eed5a9ee7c802e7151ee9939ed604032886639 commit: 37eed5a9ee7c802e7151ee9939ed604032886639 branch: master author: Ned Deily committer: GitHub date: 2020-06-07T22:24:33-04:00 summary: bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) files: A Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 76553c93a4957..86a09ae5254a3 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -313,9 +313,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.31.1", - url="https://sqlite.org/2020/sqlite-autoconf-3310100.tar.gz", - checksum='2d0a553534c521504e3ac3ad3b90f125', + name="SQLite 3.32.2", + url="https://sqlite.org/2020/sqlite-autoconf-3320200.tar.gz", + checksum='eb498918a33159cdf8104997aad29e83', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' diff --git a/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst new file mode 100644 index 0000000000000..6ff7b9a805b95 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst @@ -0,0 +1 @@ +Update macOS installer to use SQLite 3.32.2. From webhook-mailer at python.org Sun Jun 7 22:42:25 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 02:42:25 -0000 Subject: [Python-checkins] bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) Message-ID: https://github.com/python/cpython/commit/d1c449a5c6e1cd1f245ec8b721c0f32675d63872 commit: d1c449a5c6e1cd1f245ec8b721c0f32675d63872 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-07T19:42:16-07:00 summary: bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) (cherry picked from commit 37eed5a9ee7c802e7151ee9939ed604032886639) Co-authored-by: Ned Deily files: A Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 2b48cdfb860f7..8bde04ee04630 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -313,9 +313,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.31.1", - url="https://sqlite.org/2020/sqlite-autoconf-3310100.tar.gz", - checksum='2d0a553534c521504e3ac3ad3b90f125', + name="SQLite 3.32.2", + url="https://sqlite.org/2020/sqlite-autoconf-3320200.tar.gz", + checksum='eb498918a33159cdf8104997aad29e83', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' diff --git a/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst new file mode 100644 index 0000000000000..6ff7b9a805b95 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst @@ -0,0 +1 @@ +Update macOS installer to use SQLite 3.32.2. From webhook-mailer at python.org Sun Jun 7 22:43:39 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 02:43:39 -0000 Subject: [Python-checkins] bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) Message-ID: https://github.com/python/cpython/commit/264e4fd9619dfab3d9de7f78a46efd8772b03ea6 commit: 264e4fd9619dfab3d9de7f78a46efd8772b03ea6 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-07T19:43:35-07:00 summary: bpo-40741: Update macOS installer to use SQLite 3.32.2. (GH-20705) (cherry picked from commit 37eed5a9ee7c802e7151ee9939ed604032886639) Co-authored-by: Ned Deily files: A Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index bdfa6f4adf612..9d3e2a785a6c6 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -313,9 +313,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.31.1", - url="https://sqlite.org/2020/sqlite-autoconf-3310100.tar.gz", - checksum='2d0a553534c521504e3ac3ad3b90f125', + name="SQLite 3.32.2", + url="https://sqlite.org/2020/sqlite-autoconf-3320200.tar.gz", + checksum='eb498918a33159cdf8104997aad29e83', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' diff --git a/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst new file mode 100644 index 0000000000000..6ff7b9a805b95 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2020-06-07-20-10-56.bpo-40741.80A2BW.rst @@ -0,0 +1 @@ +Update macOS installer to use SQLite 3.32.2. From webhook-mailer at python.org Mon Jun 8 01:01:29 2020 From: webhook-mailer at python.org (Lysandros Nikolaou) Date: Mon, 08 Jun 2020 05:01:29 -0000 Subject: [Python-checkins] bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Message-ID: https://github.com/python/cpython/commit/7633371dace67aaa21eb4b86f889441571ec4167 commit: 7633371dace67aaa21eb4b86f889441571ec4167 branch: master author: Lysandros Nikolaou committer: GitHub date: 2020-06-07T22:01:21-07:00 summary: bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Also added an example in shutil in order to make more clear how they are to be used. Initially reported by Weinan Li on bpo. files: M Doc/library/shutil.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index c7c63e6f80844..1b094aeb9ca3d 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -570,12 +570,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. available), or "xztar" (if the :mod:`lzma` module is available). *root_dir* is a directory that will be the root directory of the - archive; for example, we typically chdir into *root_dir* before creating the - archive. + archive, all paths in the archive will be relative to it; for example, + we typically chdir into *root_dir* before creating the archive. *base_dir* is the directory where we start archiving from; i.e. *base_dir* will be the common prefix of all files and - directories in the archive. + directories in the archive. *base_dir* must be given relative + to *root_dir*. See :ref:`shutil-archiving-example-with-basedir` for how to + use *base_dir* and *root_dir* together. *root_dir* and *base_dir* both default to the current directory. @@ -727,6 +729,48 @@ The resulting archive contains: -rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts +.. _shutil-archiving-example-with-basedir: + +Archiving example with *base_dir* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this example, similar to the `one above `_, +we show how to use :func:`make_archive`, but this time with the usage of +*base_dir*. We now have the following directory structure: + +.. code-block:: shell-session + + $ tree tmp + tmp + ??? root + ??? structure + ??? content + ??? please_add.txt + ??? do_not_add.txt + +In the final archive, :file:`please_add.txt` should be included, but +:file:`do_not_add.txt` should not. Therefore we use the following:: + + >>> from shutil import make_archive + >>> import os + >>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive')) + >>> make_archive( + ... archive_name, + ... 'tar', + ... root_dir='tmp/root', + ... base_dir='structure/content', + ... ) + '/Users/tarek/my_archive.tar' + +Listing the files in the resulting archive gives us: + +.. code-block:: shell-session + + $ python -m tarfile -l /Users/tarek/myarchive.tar + structure/content/ + structure/content/please_add.txt + + Querying the size of the output terminal ---------------------------------------- From webhook-mailer at python.org Mon Jun 8 01:07:14 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 05:07:14 -0000 Subject: [Python-checkins] bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Message-ID: https://github.com/python/cpython/commit/d5489a964fadc028c7086218702daf6fae087340 commit: d5489a964fadc028c7086218702daf6fae087340 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-07T22:07:06-07:00 summary: bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Also added an example in shutil in order to make more clear how they are to be used. Initially reported by Weinan Li on bpo. (cherry picked from commit 7633371dace67aaa21eb4b86f889441571ec4167) Co-authored-by: Lysandros Nikolaou files: M Doc/library/shutil.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 12e69a4ea040c..799505858f7f5 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -477,12 +477,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. available), or "xztar" (if the :mod:`lzma` module is available). *root_dir* is a directory that will be the root directory of the - archive; for example, we typically chdir into *root_dir* before creating the - archive. + archive, all paths in the archive will be relative to it; for example, + we typically chdir into *root_dir* before creating the archive. *base_dir* is the directory where we start archiving from; i.e. *base_dir* will be the common prefix of all files and - directories in the archive. + directories in the archive. *base_dir* must be given relative + to *root_dir*. See :ref:`shutil-archiving-example-with-basedir` for how to + use *base_dir* and *root_dir* together. *root_dir* and *base_dir* both default to the current directory. @@ -626,6 +628,48 @@ The resulting archive contains: -rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts +.. _shutil-archiving-example-with-basedir: + +Archiving example with *base_dir* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this example, similar to the `one above `_, +we show how to use :func:`make_archive`, but this time with the usage of +*base_dir*. We now have the following directory structure: + +.. code-block:: shell-session + + $ tree tmp + tmp + ??? root + ??? structure + ??? content + ??? please_add.txt + ??? do_not_add.txt + +In the final archive, :file:`please_add.txt` should be included, but +:file:`do_not_add.txt` should not. Therefore we use the following:: + + >>> from shutil import make_archive + >>> import os + >>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive')) + >>> make_archive( + ... archive_name, + ... 'tar', + ... root_dir='tmp/root', + ... base_dir='structure/content', + ... ) + '/Users/tarek/my_archive.tar' + +Listing the files in the resulting archive gives us: + +.. code-block:: shell-session + + $ python -m tarfile -l /Users/tarek/myarchive.tar + structure/content/ + structure/content/please_add.txt + + Querying the size of the output terminal ---------------------------------------- From webhook-mailer at python.org Mon Jun 8 01:08:56 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 05:08:56 -0000 Subject: [Python-checkins] bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Message-ID: https://github.com/python/cpython/commit/12dfbae2ec30e7c90499129b17b6049bfd9bb2b6 commit: 12dfbae2ec30e7c90499129b17b6049bfd9bb2b6 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-07T22:08:51-07:00 summary: bpo-22021: Update root_dir and base_dir documentation in shutil (GH-10367) Also added an example in shutil in order to make more clear how they are to be used. Initially reported by Weinan Li on bpo. (cherry picked from commit 7633371dace67aaa21eb4b86f889441571ec4167) Co-authored-by: Lysandros Nikolaou files: M Doc/library/shutil.rst diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index bd24de7202321..25b749e57b27d 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -567,12 +567,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. available), or "xztar" (if the :mod:`lzma` module is available). *root_dir* is a directory that will be the root directory of the - archive; for example, we typically chdir into *root_dir* before creating the - archive. + archive, all paths in the archive will be relative to it; for example, + we typically chdir into *root_dir* before creating the archive. *base_dir* is the directory where we start archiving from; i.e. *base_dir* will be the common prefix of all files and - directories in the archive. + directories in the archive. *base_dir* must be given relative + to *root_dir*. See :ref:`shutil-archiving-example-with-basedir` for how to + use *base_dir* and *root_dir* together. *root_dir* and *base_dir* both default to the current directory. @@ -724,6 +726,48 @@ The resulting archive contains: -rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts +.. _shutil-archiving-example-with-basedir: + +Archiving example with *base_dir* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In this example, similar to the `one above `_, +we show how to use :func:`make_archive`, but this time with the usage of +*base_dir*. We now have the following directory structure: + +.. code-block:: shell-session + + $ tree tmp + tmp + ??? root + ??? structure + ??? content + ??? please_add.txt + ??? do_not_add.txt + +In the final archive, :file:`please_add.txt` should be included, but +:file:`do_not_add.txt` should not. Therefore we use the following:: + + >>> from shutil import make_archive + >>> import os + >>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive')) + >>> make_archive( + ... archive_name, + ... 'tar', + ... root_dir='tmp/root', + ... base_dir='structure/content', + ... ) + '/Users/tarek/my_archive.tar' + +Listing the files in the resulting archive gives us: + +.. code-block:: shell-session + + $ python -m tarfile -l /Users/tarek/myarchive.tar + structure/content/ + structure/content/please_add.txt + + Querying the size of the output terminal ---------------------------------------- From webhook-mailer at python.org Mon Jun 8 02:51:48 2020 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 08 Jun 2020 06:51:48 -0000 Subject: [Python-checkins] Deny eval() direct access to builtins (GH-20713) Message-ID: https://github.com/python/cpython/commit/3ff51d425ecd98b7ba5a12ca9f77eda73fbf9f53 commit: 3ff51d425ecd98b7ba5a12ca9f77eda73fbf9f53 branch: master author: Raymond Hettinger committer: GitHub date: 2020-06-07T23:51:40-07:00 summary: Deny eval() direct access to builtins (GH-20713) files: M Lib/collections/__init__.py diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 03393f35b11c5..1e3b54ccf9cc9 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -407,7 +407,8 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non # Create all the named tuple methods to be added to the class namespace s = f'lambda _cls, {arg_list}: _tuple_new(_cls, ({arg_list}))' - namespace = {'_tuple_new': tuple_new, '__name__': f'namedtuple_{typename}'} + namespace = {'_tuple_new': tuple_new, '__builtins__': None, + '__name__': f'namedtuple_{typename}'} __new__ = eval(s, namespace) __new__.__doc__ = f'Create new instance of {typename}({arg_list})' if defaults is not None: From webhook-mailer at python.org Mon Jun 8 03:52:51 2020 From: webhook-mailer at python.org (Ned Deily) Date: Mon, 08 Jun 2020 07:52:51 -0000 Subject: [Python-checkins] allow macOS installer builds to package pre-built html docs (GH-20715) Message-ID: https://github.com/python/cpython/commit/63fc55b2eab0331465605a49bfd28a1bcb997f92 commit: 63fc55b2eab0331465605a49bfd28a1bcb997f92 branch: master author: Ned Deily committer: GitHub date: 2020-06-08T03:52:43-04:00 summary: allow macOS installer builds to package pre-built html docs (GH-20715) build-installer now looks in its directory of source tarballs for a suitable html tarball of the same version. If so, it will unpack and use it rather than rebuilding the html format documentation set from the source repo. This is intended as a speedup for test builds of the installer. Files names must be in the same format as produced by the docs build for download, for example, `python-3.9.0b1-docs-html.tar.bz2`. files: M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 86a09ae5254a3..a2cba3210211d 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1066,14 +1066,40 @@ def buildPythonDocs(): curDir = os.getcwd() os.chdir(buildDir) runCommand('make clean') - # Create virtual environment for docs builds with blurb and sphinx - runCommand('make venv') - runCommand('venv/bin/python3 -m pip install -U Sphinx==2.2.0') - runCommand('make html PYTHON=venv/bin/python') + + # Search third-party source directory for a pre-built version of the docs. + # Use the naming convention of the docs.python.org html downloads: + # python-3.9.0b1-docs-html.tar.bz2 + doctarfiles = [ f for f in os.listdir(DEPSRC) + if f.startswith('python-'+getFullVersion()) + if f.endswith('-docs-html.tar.bz2') ] + if doctarfiles: + doctarfile = doctarfiles[0] + if not os.path.exists('build'): + os.mkdir('build') + # if build directory existed, it was emptied by make clean, above + os.chdir('build') + # Extract the first archive found for this version into build + runCommand('tar xjf %s'%shellQuote(os.path.join(DEPSRC, doctarfile))) + # see if tar extracted a directory ending in -docs-html + archivefiles = [ f for f in os.listdir('.') + if f.endswith('-docs-html') + if os.path.isdir(f) ] + if archivefiles: + archivefile = archivefiles[0] + # make it our 'Docs/build/html' directory + print(' -- using pre-built python documentation from %s'%archivefile) + os.rename(archivefile, 'html') + os.chdir(buildDir) + + htmlDir = os.path.join('build', 'html') + if not os.path.exists(htmlDir): + # Create virtual environment for docs builds with blurb and sphinx + runCommand('make venv') + runCommand('venv/bin/python3 -m pip install -U Sphinx==2.2.0') + runCommand('make html PYTHON=venv/bin/python') + os.rename(htmlDir, docdir) os.chdir(curDir) - if not os.path.exists(docdir): - os.mkdir(docdir) - os.rename(os.path.join(buildDir, 'build', 'html'), docdir) def buildPython(): From webhook-mailer at python.org Mon Jun 8 10:11:53 2020 From: webhook-mailer at python.org (Shantanu) Date: Mon, 08 Jun 2020 14:11:53 -0000 Subject: [Python-checkins] bpo-33187: Document 3.9 changes to xml.etree.ElementInclude.include (GH-20438) Message-ID: https://github.com/python/cpython/commit/301f0d4ff9b6bd60599eea0612904f65a92e6dd9 commit: 301f0d4ff9b6bd60599eea0612904f65a92e6dd9 branch: master author: Shantanu committer: GitHub date: 2020-06-08T16:11:44+02:00 summary: bpo-33187: Document 3.9 changes to xml.etree.ElementInclude.include (GH-20438) Looks like the merging of bpo-33187 and bpo-20928 was racy, resulting in this change going undocumented. files: M Doc/library/xml.etree.elementtree.rst diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 658bc3a54f86e..2085a85927e46 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -816,16 +816,25 @@ Functions loader fails, it can return None or raise an exception. -.. function:: xml.etree.ElementInclude.include( elem, loader=None) +.. function:: xml.etree.ElementInclude.include( elem, loader=None, base_url=None, \ + max_depth=6) This function expands XInclude directives. *elem* is the root element. *loader* is an optional resource loader. If omitted, it defaults to :func:`default_loader`. If given, it should be a callable that implements the same interface as - :func:`default_loader`. Returns the expanded resource. If the parse mode is + :func:`default_loader`. *base_url* is base URL of the original file, to resolve + relative include file references. *max_depth* is the maximum number of recursive + inclusions. Limited to reduce the risk of malicious content explosion. Pass a + negative value to disable the limitation. + + Returns the expanded resource. If the parse mode is ``"xml"``, this is an ElementTree instance. If the parse mode is "text", this is a Unicode string. If the loader fails, it can return None or raise an exception. + .. versionadded:: 3.9 + The *base_url* and *max_depth* parameters. + .. _elementtree-element-objects: From webhook-mailer at python.org Mon Jun 8 10:30:38 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jun 2020 14:30:38 -0000 Subject: [Python-checkins] bpo-29882: Add _Py_popcount32() function (GH-20518) Message-ID: https://github.com/python/cpython/commit/c6b292cdeee689f0bfac6c1e2c2d4e4e01fa8d9e commit: c6b292cdeee689f0bfac6c1e2c2d4e4e01fa8d9e branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T16:30:33+02:00 summary: bpo-29882: Add _Py_popcount32() function (GH-20518) * Rename pycore_byteswap.h to pycore_bitutils.h. * Move popcount_digit() to pycore_bitutils.h as _Py_popcount32(). * _Py_popcount32() uses GCC and clang builtin function if available. * Add unit tests to _Py_popcount32(). files: A Include/internal/pycore_bitutils.h D Include/internal/pycore_byteswap.h M Makefile.pre.in M Modules/_ctypes/cfield.c M Modules/_testinternalcapi.c M Modules/sha256module.c M Modules/sha512module.c M Objects/longobject.c M Objects/stringlib/codecs.h M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/hamt.c diff --git a/Include/internal/pycore_byteswap.h b/Include/internal/pycore_bitutils.h similarity index 59% rename from Include/internal/pycore_byteswap.h rename to Include/internal/pycore_bitutils.h index 5e64704a004c8..36ffe23b9ff26 100644 --- a/Include/internal/pycore_byteswap.h +++ b/Include/internal/pycore_bitutils.h @@ -1,4 +1,6 @@ -/* Bytes swap functions, reverse order of bytes: +/* Bit and bytes utilities. + + Bytes swap functions, reverse order of bytes: - _Py_bswap16(uint16_t) - _Py_bswap32(uint32_t) @@ -82,6 +84,53 @@ _Py_bswap64(uint64_t word) } +// Population count: count the number of 1's in 'x' +// (number of bits set to 1), also known as the hamming weight. +// +// Implementation note. CPUID is not used, to test if x86 POPCNT instruction +// can be used, to keep the implementation simple. For example, Visual Studio +// __popcnt() is not used this reason. The clang and GCC builtin function can +// use the x86 POPCNT instruction if the target architecture has SSE4a or +// newer. +static inline int +_Py_popcount32(uint32_t x) +{ +#if (defined(__clang__) || defined(__GNUC__)) + +#if SIZEOF_INT >= 4 + Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned int)); + return __builtin_popcount(x); +#else + // The C standard guarantees that unsigned long will always be big enough + // to hold a uint32_t value without losing information. + Py_BUILD_ASSERT(sizeof(x) <= sizeof(unsigned long)); + return __builtin_popcountl(x); +#endif + +#else + // 32-bit SWAR (SIMD Within A Register) popcount + + // Binary: 0 1 0 1 ... + const uint32_t M1 = 0x55555555; + // Binary: 00 11 00 11. .. + const uint32_t M2 = 0x33333333; + // Binary: 0000 1111 0000 1111 ... + const uint32_t M4 = 0x0F0F0F0F; + // 256**4 + 256**3 + 256**2 + 256**1 + const uint32_t SUM = 0x01010101; + + // Put count of each 2 bits into those 2 bits + x = x - ((x >> 1) & M1); + // Put count of each 4 bits into those 4 bits + x = (x & M2) + ((x >> 2) & M2); + // Put count of each 8 bits into those 8 bits + x = (x + (x >> 4)) & M4; + // Sum of the 4 byte counts + return (uint32_t)((uint64_t)x * (uint64_t)SUM) >> 24; +#endif +} + + #ifdef __cplusplus } #endif diff --git a/Makefile.pre.in b/Makefile.pre.in index 5a18704e44198..b115e7fc01f74 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1121,7 +1121,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_abstract.h \ $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_atomic.h \ - $(srcdir)/Include/internal/pycore_byteswap.h \ + $(srcdir)/Include/internal/pycore_bitutils.h \ $(srcdir)/Include/internal/pycore_bytes_methods.h \ $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 32a2beeb744f7..3a9b7119201cf 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include #ifdef MS_WIN32 diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 5f217dcb8978e..6d5af5917f1f0 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -12,7 +12,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include "pycore_initconfig.h" // _Py_GetConfigsAsDict() #include "pycore_hashtable.h" // _Py_hashtable_new() #include "pycore_gc.h" // PyGC_Head @@ -63,6 +63,45 @@ test_bswap(PyObject *self, PyObject *Py_UNUSED(args)) } +static int +check_popcount(uint32_t x, int expected) +{ + // Use volatile to prevent the compiler to optimize out the whole test + volatile uint32_t u = x; + int bits = _Py_popcount32(u); + if (bits != expected) { + PyErr_Format(PyExc_AssertionError, + "_Py_popcount32(%lu) returns %i, expected %i", + (unsigned long)x, bits, expected); + return -1; + } + return 0; +} + + +static PyObject* +test_popcount(PyObject *self, PyObject *Py_UNUSED(args)) +{ +#define CHECK(X, RESULT) \ + do { \ + if (check_popcount(X, RESULT) < 0) { \ + return NULL; \ + } \ + } while (0) + + CHECK(0, 0); + CHECK(1, 1); + CHECK(0x08080808, 4); + CHECK(0x10101010, 4); + CHECK(0x10204080, 4); + CHECK(0xDEADCAFE, 22); + CHECK(0xFFFFFFFF, 32); + Py_RETURN_NONE; + +#undef CHECK +} + + #define TO_PTR(ch) ((void*)(uintptr_t)ch) #define FROM_PTR(ptr) ((uintptr_t)ptr) #define VALUE(key) (1 + ((int)(key) - 'a')) @@ -157,6 +196,7 @@ static PyMethodDef TestMethods[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, {"test_bswap", test_bswap, METH_NOARGS}, + {"test_popcount", test_popcount, METH_NOARGS}, {"test_hashtable", test_hashtable, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 8edb1d5382883..261f9daee2807 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -17,7 +17,7 @@ /* SHA objects */ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include "structmember.h" // PyMemberDef #include "hashlib.h" #include "pystrhex.h" diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 561ef8ef0e867..aa2aeedcc6c64 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -17,7 +17,7 @@ /* SHA objects */ #include "Python.h" -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() #include "structmember.h" // PyMemberDef #include "hashlib.h" #include "pystrhex.h" diff --git a/Objects/longobject.c b/Objects/longobject.c index 0b209a403c4b7..ce10c4f66586a 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3,8 +3,9 @@ /* XXX The functional organization of this file is terrible */ #include "Python.h" -#include "pycore_interp.h" // _PY_NSMALLPOSINTS -#include "pycore_pystate.h" // _Py_IsMainInterpreter() +#include "pycore_bitutils.h" // _Py_popcount32() +#include "pycore_interp.h" // _PY_NSMALLPOSINTS +#include "pycore_pystate.h" // _Py_IsMainInterpreter() #include "longintrepr.h" #include @@ -5307,12 +5308,10 @@ int_bit_length_impl(PyObject *self) static int popcount_digit(digit d) { - /* 32bit SWAR popcount. */ - uint32_t u = d; - u -= (u >> 1) & 0x55555555U; - u = (u & 0x33333333U) + ((u >> 2) & 0x33333333U); - u = (u + (u >> 4)) & 0x0f0f0f0fU; - return (uint32_t)(u * 0x01010101U) >> 24; + // digit can be larger than uint32_t, but only PyLong_SHIFT bits + // of it will be ever used. + Py_BUILD_ASSERT(PyLong_SHIFT <= 32); + return _Py_popcount32((uint32_t)d); } /*[clinic input] diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 9b2a29ba3b8c2..197605b012e5c 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -4,7 +4,7 @@ # error "codecs.h is specific to Unicode" #endif -#include "pycore_byteswap.h" // _Py_bswap32() +#include "pycore_bitutils.h" // _Py_bswap32() /* Mask to quickly check whether a C 'long' contains a non-ASCII, UTF8-encoded char. */ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index b6b0cf3e991ba..8d5f99f8336a3 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -170,7 +170,7 @@ - + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 10dfffba6113e..7bc9f8f166456 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -201,7 +201,7 @@ Include - + Include diff --git a/Python/hamt.c b/Python/hamt.c index 8801c5ea418c7..e272e8808fd95 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -1,5 +1,6 @@ #include "Python.h" +#include "pycore_bitutils.h" // _Py_popcount32 #include "pycore_hamt.h" #include "pycore_object.h" // _PyObject_GC_TRACK() #include // offsetof() @@ -433,30 +434,10 @@ hamt_bitpos(int32_t hash, uint32_t shift) return (uint32_t)1 << hamt_mask(hash, shift); } -static inline uint32_t -hamt_bitcount(uint32_t i) -{ - /* We could use native popcount instruction but that would - require to either add configure flags to enable SSE4.2 - support or to detect it dynamically. Otherwise, we have - a risk of CPython not working properly on older hardware. - - In practice, there's no observable difference in - performance between using a popcount instruction or the - following fallback code. - - The algorithm is copied from: - https://graphics.stanford.edu/~seander/bithacks.html - */ - i = i - ((i >> 1) & 0x55555555); - i = (i & 0x33333333) + ((i >> 2) & 0x33333333); - return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; -} - static inline uint32_t hamt_bitindex(uint32_t bitmap, uint32_t bit) { - return hamt_bitcount(bitmap & (bit - 1)); + return (uint32_t)_Py_popcount32(bitmap & (bit - 1)); } @@ -820,7 +801,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, else { /* There was no key before with the same (shift,hash). */ - uint32_t n = hamt_bitcount(self->b_bitmap); + uint32_t n = (uint32_t)_Py_popcount32(self->b_bitmap); if (n >= 16) { /* When we have a situation where we want to store more From webhook-mailer at python.org Mon Jun 8 11:28:21 2020 From: webhook-mailer at python.org (Sandro Mani) Date: Mon, 08 Jun 2020 15:28:21 -0000 Subject: [Python-checkins] bpo-40854: Allow overriding sys.platlibdir via PYTHONPLATLIBDIR env-var (GH-20605) Message-ID: https://github.com/python/cpython/commit/8f023a2f664f902a3d0b7a6f64d63afc0d1c15ae commit: 8f023a2f664f902a3d0b7a6f64d63afc0d1c15ae branch: master author: Sandro Mani committer: GitHub date: 2020-06-08T17:28:11+02:00 summary: bpo-40854: Allow overriding sys.platlibdir via PYTHONPLATLIBDIR env-var (GH-20605) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst M Doc/c-api/init_config.rst M Doc/using/cmdline.rst M Include/cpython/initconfig.h M Lib/test/test_embed.py M Makefile.pre.in M Misc/python.man M Modules/getpath.c M Programs/_testembed.c M Python/initconfig.c M Python/sysmodule.c diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index fc82c3eb59024..7b8e894fe22dd 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -436,6 +436,14 @@ PyConfig :data:`sys.base_prefix`. + .. c:member:: wchar_t* platlibdir + + :data:`sys.platlibdir`: platform library directory name, set at configure time + by ``--with-platlibdir``, overrideable by the ``PYTHONPLATLIBDIR`` + environment variable. + + .. versionadded:: 3.10 + .. c:member:: int buffered_stdio If equals to 0, enable unbuffered mode, making the stdout and stderr @@ -884,6 +892,7 @@ Path Configuration * Path configuration inputs: * :c:member:`PyConfig.home` + * :c:member:`PyConfig.platlibdir` * :c:member:`PyConfig.pathconfig_warnings` * :c:member:`PyConfig.program_name` * :c:member:`PyConfig.pythonpath_env` diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b0911956a9eb8..3e0797279d6bf 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -538,6 +538,14 @@ conflict. within a Python program as the variable :data:`sys.path`. +.. envvar:: PYTHONPLATLIBDIR + + If this is set to a non-empty string, it overrides the :data:`sys.platlibdir` + value. + + .. versionadded:: 3.10 + + .. envvar:: PYTHONSTARTUP If this is the name of a readable file, the Python commands in that file are diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index e9c2e6bec3861..563c2bacfa428 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -385,6 +385,7 @@ typedef struct { wchar_t *base_prefix; /* sys.base_prefix */ wchar_t *exec_prefix; /* sys.exec_prefix */ wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ + wchar_t *platlibdir; /* sys.platlibdir */ /* --- Parameter only used by Py_Main() ---------- */ diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 3d60b2f330c62..f1371db866924 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -380,6 +380,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'exec_prefix': GET_DEFAULT_CONFIG, 'base_exec_prefix': GET_DEFAULT_CONFIG, 'module_search_paths': GET_DEFAULT_CONFIG, + 'platlibdir': sys.platlibdir, 'site_import': 1, 'bytes_warning': 0, @@ -585,13 +586,14 @@ def get_expected_config(self, expected_preconfig, expected, env, api, if value is self.GET_DEFAULT_CONFIG: expected[key] = config[key] - pythonpath_env = expected['pythonpath_env'] - if pythonpath_env is not None: - paths = pythonpath_env.split(os.path.pathsep) - expected['module_search_paths'] = [*paths, *expected['module_search_paths']] - if modify_path_cb is not None: - expected['module_search_paths'] = expected['module_search_paths'].copy() - modify_path_cb(expected['module_search_paths']) + if expected['module_search_paths'] is not self.IGNORE_CONFIG: + pythonpath_env = expected['pythonpath_env'] + if pythonpath_env is not None: + paths = pythonpath_env.split(os.path.pathsep) + expected['module_search_paths'] = [*paths, *expected['module_search_paths']] + if modify_path_cb is not None: + expected['module_search_paths'] = expected['module_search_paths'].copy() + modify_path_cb(expected['module_search_paths']) for key in self.COPY_PRE_CONFIG: if key not in expected_preconfig: @@ -764,6 +766,8 @@ def test_init_from_config(self): 'buffered_stdio': 0, 'user_site_directory': 0, 'faulthandler': 1, + 'platlibdir': 'my_platlibdir', + 'module_search_paths': self.IGNORE_CONFIG, 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, @@ -795,6 +799,8 @@ def test_init_compat_env(self): 'user_site_directory': 0, 'faulthandler': 1, 'warnoptions': ['EnvVar'], + 'platlibdir': 'env_platlibdir', + 'module_search_paths': self.IGNORE_CONFIG, '_use_peg_parser': 0, } self.check_all_configs("test_init_compat_env", config, preconfig, @@ -823,6 +829,8 @@ def test_init_python_env(self): 'user_site_directory': 0, 'faulthandler': 1, 'warnoptions': ['EnvVar'], + 'platlibdir': 'env_platlibdir', + 'module_search_paths': self.IGNORE_CONFIG, '_use_peg_parser': 0, } self.check_all_configs("test_init_python_env", config, preconfig, diff --git a/Makefile.pre.in b/Makefile.pre.in index b115e7fc01f74..9cb7a23eea582 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -811,6 +811,11 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydt $(MULTIARCH_CPPFLAGS) \ -o $@ $(srcdir)/Python/sysmodule.c +Python/initconfig.o: $(srcdir)/Python/initconfig.c + $(CC) -c $(PY_CORE_CFLAGS) \ + -DPLATLIBDIR='"$(PLATLIBDIR)"' \ + -o $@ $(srcdir)/Python/initconfig.c + $(IO_OBJS): $(IO_H) .PHONY: regen-grammar diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst new file mode 100644 index 0000000000000..6ef4ed5af7318 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-03-13-53-24.bpo-40854.O6vfQU.rst @@ -0,0 +1 @@ +Allow overriding :data:`sys.platlibdir` via a new :envvar:`PYTHONPLATLIBDIR` environment variable. diff --git a/Misc/python.man b/Misc/python.man index 89a15a5e7b2ff..74b2d72939eeb 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -413,6 +413,8 @@ inserted in the path in front of $PYTHONPATH. The search path can be manipulated from within a Python program as the variable .IR sys.path . +.IP PYTHONPLATLIBDIR +Override sys.platlibdir. .IP PYTHONSTARTUP If this is the name of a readable file, the Python commands in that file are executed before the first prompt is displayed in interactive diff --git a/Modules/getpath.c b/Modules/getpath.c index d9829f8ad3dbd..469c9ca010640 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -105,8 +105,8 @@ extern "C" { #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \ - || !defined(VERSION) || !defined(VPATH) || !defined(PLATLIBDIR)) -#error "PREFIX, EXEC_PREFIX, VERSION, VPATH and PLATLIBDIR macros must be defined" + || !defined(VERSION) || !defined(VPATH)) +#error "PREFIX, EXEC_PREFIX, VERSION and VPATH macros must be defined" #endif #ifndef LANDMARK @@ -128,7 +128,6 @@ typedef struct { wchar_t *pythonpath_macro; /* PYTHONPATH macro */ wchar_t *prefix_macro; /* PREFIX macro */ wchar_t *exec_prefix_macro; /* EXEC_PREFIX macro */ - wchar_t *platlibdir_macro; /* PLATLIBDIR macro */ wchar_t *vpath_macro; /* VPATH macro */ wchar_t *lib_python; /* "lib/pythonX.Y" */ @@ -138,6 +137,7 @@ typedef struct { int warnings; const wchar_t *pythonpath_env; + const wchar_t *platlibdir; wchar_t *argv0_path; wchar_t *zip_path; @@ -811,7 +811,7 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) } /* / "lib-dynload" */ - wchar_t *lib_dynload = joinpath2(calculate->platlibdir_macro, + wchar_t *lib_dynload = joinpath2(calculate->platlibdir, L"lib-dynload"); if (lib_dynload == NULL) { return _PyStatus_NO_MEMORY(); @@ -1297,7 +1297,7 @@ calculate_zip_path(PyCalculatePath *calculate) PyStatus res; /* Path: / "pythonXY.zip" */ - wchar_t *path = joinpath2(calculate->platlibdir_macro, L"python" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) L".zip"); + wchar_t *path = joinpath2(calculate->platlibdir, L"python" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) L".zip"); if (path == NULL) { return _PyStatus_NO_MEMORY(); } @@ -1451,10 +1451,6 @@ calculate_init(PyCalculatePath *calculate, const PyConfig *config) if (!calculate->vpath_macro) { return DECODE_LOCALE_ERR("VPATH macro", len); } - calculate->platlibdir_macro = Py_DecodeLocale(PLATLIBDIR, &len); - if (!calculate->platlibdir_macro) { - return DECODE_LOCALE_ERR("PLATLIBDIR macro", len); - } calculate->lib_python = Py_DecodeLocale(PLATLIBDIR "/python" VERSION, &len); if (!calculate->lib_python) { @@ -1463,6 +1459,7 @@ calculate_init(PyCalculatePath *calculate, const PyConfig *config) calculate->warnings = config->pathconfig_warnings; calculate->pythonpath_env = config->pythonpath_env; + calculate->platlibdir = config->platlibdir; return _PyStatus_OK(); } @@ -1475,7 +1472,6 @@ calculate_free(PyCalculatePath *calculate) PyMem_RawFree(calculate->prefix_macro); PyMem_RawFree(calculate->exec_prefix_macro); PyMem_RawFree(calculate->vpath_macro); - PyMem_RawFree(calculate->platlibdir_macro); PyMem_RawFree(calculate->lib_python); PyMem_RawFree(calculate->path_env); PyMem_RawFree(calculate->zip_path); diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 5c83678f650d0..11524dfbc0d58 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -548,6 +548,13 @@ static int test_init_from_config(void) /* FIXME: test home */ /* FIXME: test path config: module_search_path .. dll_path */ + putenv("PYTHONPLATLIBDIR=env_platlibdir"); + status = PyConfig_SetBytesString(&config, &config.platlibdir, "my_platlibdir"); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + putenv("PYTHONVERBOSE=0"); Py_VerboseFlag = 0; config.verbose = 1; @@ -668,6 +675,7 @@ static void set_most_env_vars(void) putenv("PYTHONFAULTHANDLER=1"); putenv("PYTHONIOENCODING=iso8859-1:replace"); putenv("PYTHONOLDPARSER=1"); + putenv("PYTHONPLATLIBDIR=env_platlibdir"); } diff --git a/Python/initconfig.c b/Python/initconfig.c index 185935c05fb28..834b8ed943023 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -24,6 +24,10 @@ # endif #endif +#ifndef PLATLIBDIR +# error "PLATLIBDIR macro must be defined" +#endif + /* --- Command line options --------------------------------------- */ @@ -110,6 +114,7 @@ PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\ static const char usage_5[] = "PYTHONHOME : alternate directory (or %lc).\n" " The default module search path uses %s.\n" +"PYTHONPLATLIBDIR : override sys.platlibdir.\n" "PYTHONCASEOK : ignore case in 'import' statements (Windows).\n" "PYTHONUTF8: if set to 1, enable the UTF-8 mode.\n" "PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n" @@ -588,6 +593,7 @@ PyConfig_Clear(PyConfig *config) CLEAR(config->base_prefix); CLEAR(config->exec_prefix); CLEAR(config->base_exec_prefix); + CLEAR(config->platlibdir); CLEAR(config->filesystem_encoding); CLEAR(config->filesystem_errors); @@ -824,6 +830,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_WSTR_ATTR(base_prefix); COPY_WSTR_ATTR(exec_prefix); COPY_WSTR_ATTR(base_exec_prefix); + COPY_WSTR_ATTR(platlibdir); COPY_ATTR(site_import); COPY_ATTR(bytes_warning); @@ -926,6 +933,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_WSTR(base_prefix); SET_ITEM_WSTR(exec_prefix); SET_ITEM_WSTR(base_exec_prefix); + SET_ITEM_WSTR(platlibdir); SET_ITEM_INT(site_import); SET_ITEM_INT(bytes_warning); SET_ITEM_INT(inspect); @@ -1336,6 +1344,14 @@ config_read_env_vars(PyConfig *config) } } + if(config->platlibdir == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->platlibdir, + L"PYTHONPLATLIBDIR", "PYTHONPLATLIBDIR"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->use_hash_seed < 0) { status = config_init_hash_seed(config); if (_PyStatus_EXCEPTION(status)) { @@ -1731,6 +1747,14 @@ config_read(PyConfig *config) } } + if(config->platlibdir == NULL) { + status = CONFIG_SET_BYTES_STR(config, &config->platlibdir, PLATLIBDIR, + "PLATLIBDIR macro"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + if (config->_install_importlib) { status = _PyConfig_InitPathConfig(config); if (_PyStatus_EXCEPTION(status)) { @@ -2554,6 +2578,7 @@ PyConfig_Read(PyConfig *config) assert(config->exec_prefix != NULL); assert(config->base_exec_prefix != NULL); } + assert(config->platlibdir != NULL); assert(config->filesystem_encoding != NULL); assert(config->filesystem_errors != NULL); assert(config->stdio_encoding != NULL); @@ -2704,6 +2729,7 @@ _Py_DumpPathConfig(PyThreadState *tstate) DUMP_SYS(_base_executable); DUMP_SYS(base_prefix); DUMP_SYS(base_exec_prefix); + DUMP_SYS(platlibdir); DUMP_SYS(executable); DUMP_SYS(prefix); DUMP_SYS(exec_prefix); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index e3fe1436145b4..3e4115fe8e1f9 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2922,13 +2922,7 @@ _PySys_InitMain(PyThreadState *tstate) SET_SYS_FROM_WSTR("base_prefix", config->base_prefix); SET_SYS_FROM_WSTR("exec_prefix", config->exec_prefix); SET_SYS_FROM_WSTR("base_exec_prefix", config->base_exec_prefix); - { - PyObject *str = PyUnicode_FromString(PLATLIBDIR); - if (str == NULL) { - return -1; - } - SET_SYS_FROM_STRING("platlibdir", str); - } + SET_SYS_FROM_WSTR("platlibdir", config->platlibdir); if (config->pycache_prefix != NULL) { SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); From webhook-mailer at python.org Mon Jun 8 12:13:08 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jun 2020 16:13:08 -0000 Subject: [Python-checkins] bpo-40910: Export Py_GetArgcArgv() function (GH-20721) Message-ID: https://github.com/python/cpython/commit/e81f6e687d0f04a45f2389d0b43fafd6d8491624 commit: e81f6e687d0f04a45f2389d0b43fafd6d8491624 branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T18:12:59+02:00 summary: bpo-40910: Export Py_GetArgcArgv() function (GH-20721) Export explicitly the Py_GetArgcArgv() function to the C API and document the function. Previously, it was exported implicitly which no longer works since Python is built with -fvisibility=hidden. * Add PyConfig._orig_argv member. * Py_InitializeFromConfig() no longer calls _PyConfig_Write() twice. * PyConfig_Read() no longer initializes Py_GetArgcArgv(): it is now _PyConfig_Write() responsibility. * _PyConfig_Write() result type becomes PyStatus instead of void. * Write an unit test on Py_GetArgcArgv(). files: A Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst M Doc/c-api/init_config.rst M Include/cpython/initconfig.h M Include/internal/pycore_initconfig.h M Lib/test/test_embed.py M PC/python3.def M Programs/_testembed.c M Python/bootstrap_hash.c M Python/initconfig.c M Python/pylifecycle.c diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 7b8e894fe22dd..c51b157bbb33e 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -43,6 +43,7 @@ Functions: * :c:func:`Py_PreInitializeFromArgs` * :c:func:`Py_PreInitializeFromBytesArgs` * :c:func:`Py_RunMain` +* :c:func:`Py_GetArgcArgv` The preconfiguration (``PyPreConfig`` type) is stored in ``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in @@ -984,6 +985,14 @@ customized Python always running in isolated mode using :c:func:`Py_RunMain`. +Py_GetArgcArgv() +---------------- + +.. c:function:: void Py_GetArgcArgv(int *argc, wchar_t ***argv) + + Get the original command line arguments, before Python modified them. + + Multi-Phase Initialization Private Provisional API -------------------------------------------------- diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 563c2bacfa428..57933211bb937 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -411,6 +411,14 @@ typedef struct { /* If non-zero, disallow threads, subprocesses, and fork. Default: 0. */ int _isolated_interpreter; + + /* Original command line arguments. If _orig_argv is empty and _argv is + not equal to [''], PyConfig_Read() copies the configuration 'argv' list + into '_orig_argv' list before modifying 'argv' list (if parse_argv + is non-zero). + + _PyConfig_Write() initializes Py_GetArgcArgv() to this list. */ + PyWideStringList _orig_argv; } PyConfig; PyAPI_FUNC(void) PyConfig_InitPythonConfig(PyConfig *config); @@ -436,5 +444,13 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items); + +/* --- Helper functions --------------------------------------- */ + +/* Get the original command line arguments, before Python modified them. + + See also PyConfig._orig_argv. */ +PyAPI_FUNC(void) Py_GetArgcArgv(int *argc, wchar_t ***argv); + #endif /* !Py_LIMITED_API */ #endif /* !Py_PYCORECONFIG_H */ diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h index 8c6706c95cbd1..457a005860b20 100644 --- a/Include/internal/pycore_initconfig.h +++ b/Include/internal/pycore_initconfig.h @@ -150,7 +150,7 @@ extern PyStatus _PyConfig_Copy( PyConfig *config, const PyConfig *config2); extern PyStatus _PyConfig_InitPathConfig(PyConfig *config); -extern void _PyConfig_Write(const PyConfig *config, +extern PyStatus _PyConfig_Write(const PyConfig *config, struct pyruntimestate *runtime); extern PyStatus _PyConfig_SetPyArgv( PyConfig *config, diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index f1371db866924..b7b70589da52b 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -366,6 +366,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'program_name': GET_DEFAULT_CONFIG, 'parse_argv': 0, 'argv': [""], + '_orig_argv': [], 'xoptions': [], 'warnoptions': [], @@ -739,7 +740,12 @@ def test_init_from_config(self): 'pycache_prefix': 'conf_pycache_prefix', 'program_name': './conf_program_name', - 'argv': ['-c', 'arg2', ], + 'argv': ['-c', 'arg2'], + '_orig_argv': ['python3', + '-W', 'cmdline_warnoption', + '-X', 'cmdline_xoption', + '-c', 'pass', + 'arg2'], 'parse_argv': 1, 'xoptions': [ 'config_xoption1=3', @@ -872,6 +878,7 @@ def test_preinit_parse_argv(self): } config = { 'argv': ['script.py'], + '_orig_argv': ['python3', '-X', 'dev', 'script.py'], 'run_filename': os.path.abspath('script.py'), 'dev_mode': 1, 'faulthandler': 1, @@ -886,9 +893,14 @@ def test_preinit_dont_parse_argv(self): preconfig = { 'isolated': 0, } + argv = ["python3", + "-E", "-I", + "-X", "dev", + "-X", "utf8", + "script.py"] config = { - 'argv': ["python3", "-E", "-I", - "-X", "dev", "-X", "utf8", "script.py"], + 'argv': argv, + '_orig_argv': argv, 'isolated': 0, } self.check_all_configs("test_preinit_dont_parse_argv", config, preconfig, @@ -967,6 +979,9 @@ def test_init_sys_add(self): 'ignore:::sysadd_warnoption', 'ignore:::config_warnoption', ], + '_orig_argv': ['python3', + '-W', 'ignore:::cmdline_warnoption', + '-X', 'cmdline_xoption'], } self.check_all_configs("test_init_sys_add", config, api=API_PYTHON) @@ -975,6 +990,7 @@ def test_init_run_main(self): 'print(json.dumps(_testinternalcapi.get_configs()))') config = { 'argv': ['-c', 'arg2'], + '_orig_argv': ['python3', '-c', code, 'arg2'], 'program_name': './python3', 'run_command': code + '\n', 'parse_argv': 1, @@ -986,6 +1002,9 @@ def test_init_main(self): 'print(json.dumps(_testinternalcapi.get_configs()))') config = { 'argv': ['-c', 'arg2'], + '_orig_argv': ['python3', + '-c', code, + 'arg2'], 'program_name': './python3', 'run_command': code + '\n', 'parse_argv': 1, @@ -999,6 +1018,7 @@ def test_init_parse_argv(self): config = { 'parse_argv': 1, 'argv': ['-c', 'arg1', '-v', 'arg3'], + '_orig_argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', 'run_command': 'pass\n', 'use_environment': 0, @@ -1012,6 +1032,7 @@ def test_init_dont_parse_argv(self): config = { 'parse_argv': 0, 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], + '_orig_argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } self.check_all_configs("test_init_dont_parse_argv", config, pre_config, @@ -1299,10 +1320,17 @@ def test_init_warnoptions(self): 'faulthandler': 1, 'bytes_warning': 1, 'warnoptions': warnoptions, + '_orig_argv': ['python3', + '-Wignore:::cmdline1', + '-Wignore:::cmdline2'], } self.check_all_configs("test_init_warnoptions", config, preconfig, api=API_PYTHON) + def test_get_argc_argv(self): + self.run_embedded_interpreter("test_get_argc_argv") + # ignore output + class AuditingTests(EmbeddingTestsMixin, unittest.TestCase): def test_open_code_hook(self): diff --git a/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst b/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst new file mode 100644 index 0000000000000..1d0cb0b0235bf --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-06-08-15-59-06.bpo-40910.L56oI0.rst @@ -0,0 +1,3 @@ +Export explicitly the :c:func:`Py_GetArgcArgv` function to the C API and +document the function. Previously, it was exported implicitly which no +longer works since Python is built with ``-fvisibility=hidden``. diff --git a/PC/python3.def b/PC/python3.def index 6d54d4eaf71f0..2a6aaf4331ea5 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -734,6 +734,7 @@ EXPORTS Py_FinalizeEx=python310.Py_FinalizeEx Py_GenericAlias=python310.Py_GenericAlias Py_GenericAliasType=python310.Py_GenericAliasType + Py_GetArgcArgv=python310.Py_GetArgcArgv Py_GetBuildInfo=python310.Py_GetBuildInfo Py_GetCompiler=python310.Py_GetCompiler Py_GetCopyright=python310.Py_GetCopyright diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 11524dfbc0d58..d89f6be6570e3 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1334,6 +1334,7 @@ static int test_init_read_set(void) return 0; fail: + PyConfig_Clear(&config); Py_ExitStatusException(status); } @@ -1592,6 +1593,46 @@ static int test_run_main(void) } +static int test_get_argc_argv(void) +{ + PyConfig config; + PyConfig_InitPythonConfig(&config); + + wchar_t *argv[] = {L"python3", L"-c", + (L"import sys; " + L"print(f'Py_RunMain(): sys.argv={sys.argv}')"), + L"arg2"}; + config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv); + config_set_string(&config, &config.program_name, L"./python3"); + + // Calling PyConfig_Read() twice must not change Py_GetArgcArgv() result. + // The second call is done by Py_InitializeFromConfig(). + PyStatus status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + + init_from_config_clear(&config); + + int get_argc; + wchar_t **get_argv; + Py_GetArgcArgv(&get_argc, &get_argv); + printf("argc: %i\n", get_argc); + assert(get_argc == Py_ARRAY_LENGTH(argv)); + for (int i=0; i < get_argc; i++) { + printf("argv[%i]: %ls\n", i, get_argv[i]); + assert(wcscmp(get_argv[i], argv[i]) == 0); + } + + Py_Finalize(); + + printf("\n"); + printf("test ok\n"); + return 0; +} + + /* ********************************************************* * List of test cases and the function that implements it. * @@ -1649,6 +1690,7 @@ static struct TestCase TestCases[] = { {"test_init_setpythonhome", test_init_setpythonhome}, {"test_init_warnoptions", test_init_warnoptions}, {"test_run_main", test_run_main}, + {"test_get_argc_argv", test_get_argc_argv}, {"test_open_code_hook", test_open_code_hook}, {"test_audit", test_audit}, diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index b2109275014b2..47369305ee88e 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -580,7 +580,7 @@ _Py_HashRandomization_Init(const PyConfig *config) res = pyurandom(secret, secret_size, 0, 0); if (res < 0) { return _PyStatus_ERR("failed to get random numbers " - "to initialize Python"); + "to initialize Python"); } } return _PyStatus_OK(); diff --git a/Python/initconfig.c b/Python/initconfig.c index 834b8ed943023..998ceb7bbfa51 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -548,8 +548,6 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) } -/* Make the *original* argc/argv available to other modules. - This is rare, but it is needed by the secureware extension. */ void Py_GetArgcArgv(int *argc, wchar_t ***argv) { @@ -859,6 +857,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(pathconfig_warnings); COPY_ATTR(_init_main); COPY_ATTR(_isolated_interpreter); + COPY_WSTRLIST(_orig_argv); #undef COPY_ATTR #undef COPY_WSTR_ATTR @@ -960,6 +959,7 @@ config_as_dict(const PyConfig *config) SET_ITEM_INT(pathconfig_warnings); SET_ITEM_INT(_init_main); SET_ITEM_INT(_isolated_interpreter); + SET_ITEM_WSTRLIST(_orig_argv); return dict; @@ -1856,7 +1856,7 @@ config_init_stdio(const PyConfig *config) - set Py_xxx global configuration variables - initialize C standard streams (stdin, stdout, stderr) */ -void +PyStatus _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) { config_set_global_vars(config); @@ -1870,6 +1870,13 @@ _PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) preconfig->isolated = config->isolated; preconfig->use_environment = config->use_environment; preconfig->dev_mode = config->dev_mode; + + if (_Py_SetArgcArgv(config->_orig_argv.length, + config->_orig_argv.items) < 0) + { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); } @@ -2493,7 +2500,6 @@ PyStatus PyConfig_Read(PyConfig *config) { PyStatus status; - PyWideStringList orig_argv = _PyWideStringList_INIT; status = _Py_PreInitializeFromConfig(config, NULL); if (_PyStatus_EXCEPTION(status)) { @@ -2502,8 +2508,13 @@ PyConfig_Read(PyConfig *config) config_get_global_vars(config); - if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) { - return _PyStatus_NO_MEMORY(); + if (config->_orig_argv.length == 0 + && !(config->argv.length == 1 + && wcscmp(config->argv.items[0], L"") == 0)) + { + if (_PyWideStringList_Copy(&config->_orig_argv, &config->argv) < 0) { + return _PyStatus_NO_MEMORY(); + } } _PyPreCmdline precmdline = _PyPreCmdline_INIT; @@ -2534,11 +2545,6 @@ PyConfig_Read(PyConfig *config) goto done; } - if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) { - status = _PyStatus_NO_MEMORY(); - goto done; - } - /* Check config consistency */ assert(config->isolated >= 0); assert(config->use_environment >= 0); @@ -2591,11 +2597,11 @@ PyConfig_Read(PyConfig *config) assert(config->check_hash_pycs_mode != NULL); assert(config->_install_importlib >= 0); assert(config->pathconfig_warnings >= 0); + assert(_PyWideStringList_CheckConsistency(&config->_orig_argv)); status = _PyStatus_OK(); done: - _PyWideStringList_Clear(&orig_argv); _PyPreCmdline_Clear(&precmdline); return status; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d730a98d3e5b9..f2f7d585c8000 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -460,7 +460,10 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime, return _PyStatus_ERR("can't make main interpreter"); } - _PyConfig_Write(config, runtime); + status = _PyConfig_Write(config, runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } status = _PyInterpreterState_SetConfig(interp, config); if (_PyStatus_EXCEPTION(status)) { @@ -486,7 +489,10 @@ pycore_init_runtime(_PyRuntimeState *runtime, return _PyStatus_ERR("main interpreter already initialized"); } - _PyConfig_Write(config, runtime); + PyStatus status = _PyConfig_Write(config, runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } /* Py_Finalize leaves _Py_Finalizing set in order to help daemon * threads behave a little more gracefully at interpreter shutdown. @@ -499,7 +505,7 @@ pycore_init_runtime(_PyRuntimeState *runtime, */ _PyRuntimeState_SetFinalizing(runtime, NULL); - PyStatus status = _Py_HashRandomization_Init(config); + status = _Py_HashRandomization_Init(config); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -746,8 +752,6 @@ pyinit_config(_PyRuntimeState *runtime, PyThreadState **tstate_p, const PyConfig *config) { - _PyConfig_Write(config, runtime); - PyStatus status = pycore_init_runtime(runtime, config); if (_PyStatus_EXCEPTION(status)) { return status; From webhook-mailer at python.org Mon Jun 8 12:48:47 2020 From: webhook-mailer at python.org (Steve Dower) Date: Mon, 08 Jun 2020 16:48:47 -0000 Subject: [Python-checkins] bpo-40861: Enable optimizations when building liblzma (GH-20724) Message-ID: https://github.com/python/cpython/commit/3a3a30c5a4622e18be9f7e4a239dc9e0d7c8054c commit: 3a3a30c5a4622e18be9f7e4a239dc9e0d7c8054c branch: master author: Steve Dower committer: GitHub date: 2020-06-08T17:48:43+01:00 summary: bpo-40861: Enable optimizations when building liblzma (GH-20724) files: M PCbuild/liblzma.vcxproj diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index 9ec062e5255f0..a6bd59ec0baa3 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -91,11 +91,8 @@ - WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions) - Level3 - ProgramDatabase - Disabled - $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple + WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) + $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) 4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings) From webhook-mailer at python.org Mon Jun 8 13:06:41 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 17:06:41 -0000 Subject: [Python-checkins] bpo-40861: Enable optimizations when building liblzma (GH-20724) Message-ID: https://github.com/python/cpython/commit/62e7f9ab55a6426708d5316da6f07d3fe220b53a commit: 62e7f9ab55a6426708d5316da6f07d3fe220b53a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-08T10:06:31-07:00 summary: bpo-40861: Enable optimizations when building liblzma (GH-20724) (cherry picked from commit 3a3a30c5a4622e18be9f7e4a239dc9e0d7c8054c) Co-authored-by: Steve Dower files: M PCbuild/liblzma.vcxproj diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index f408b5478558c..f7f3dba554b9e 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -59,11 +59,8 @@ - WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions) - Level3 - ProgramDatabase - Disabled - $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple + WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) + $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) 4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings) From webhook-mailer at python.org Mon Jun 8 13:07:36 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 17:07:36 -0000 Subject: [Python-checkins] bpo-40861: Enable optimizations when building liblzma (GH-20724) Message-ID: https://github.com/python/cpython/commit/30513b627777b936e3df8e4b6dd4d6b280a6b765 commit: 30513b627777b936e3df8e4b6dd4d6b280a6b765 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-08T10:07:27-07:00 summary: bpo-40861: Enable optimizations when building liblzma (GH-20724) (cherry picked from commit 3a3a30c5a4622e18be9f7e4a239dc9e0d7c8054c) Co-authored-by: Steve Dower files: M PCbuild/liblzma.vcxproj diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index 9ec062e5255f0..a6bd59ec0baa3 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -91,11 +91,8 @@ - WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions) - Level3 - ProgramDatabase - Disabled - $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple + WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) + $(lzmaDir)windows;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories) 4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings) From webhook-mailer at python.org Mon Jun 8 13:31:36 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 17:31:36 -0000 Subject: [Python-checkins] Remove deleted libmpdec header from the Visual Studio build machinery. (GH-20730) Message-ID: https://github.com/python/cpython/commit/0c59f440f4c9dca658e6b18db14b67b750e25a87 commit: 0c59f440f4c9dca658e6b18db14b67b750e25a87 branch: master author: Stefan Krah committer: GitHub date: 2020-06-08T19:31:29+02:00 summary: Remove deleted libmpdec header from the Visual Studio build machinery. (GH-20730) files: M PCbuild/_decimal.vcxproj M PCbuild/_decimal.vcxproj.filters diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index f0f387f3bfaa5..4c71cdb6d1d77 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -118,7 +118,6 @@ - diff --git a/PCbuild/_decimal.vcxproj.filters b/PCbuild/_decimal.vcxproj.filters index 1aa9d020d672f..5f7de3d85381e 100644 --- a/PCbuild/_decimal.vcxproj.filters +++ b/PCbuild/_decimal.vcxproj.filters @@ -57,9 +57,6 @@ Header Files - - Header Files - @@ -113,4 +110,4 @@ Source Files - \ No newline at end of file + From webhook-mailer at python.org Mon Jun 8 13:33:17 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 17:33:17 -0000 Subject: [Python-checkins] Add multicore support to deccheck.py. (GH-20731) Message-ID: https://github.com/python/cpython/commit/951d680d56d8c32556437a86f6b42f221635b97f commit: 951d680d56d8c32556437a86f6b42f221635b97f branch: master author: Stefan Krah committer: GitHub date: 2020-06-08T19:33:12+02:00 summary: Add multicore support to deccheck.py. (GH-20731) files: M Modules/_decimal/tests/deccheck.py diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 5cd5db5711426..5d9179e61689d 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -29,9 +29,20 @@ # Usage: python deccheck.py [--short|--medium|--long|--all] # -import sys, random + +import sys +import os +import time +import random from copy import copy from collections import defaultdict + +import argparse +import subprocess +from subprocess import PIPE, STDOUT +from queue import Queue, Empty +from threading import Thread, Event, Lock + from test.support import import_fresh_module from randdec import randfloat, all_unary, all_binary, all_ternary from randdec import unary_optarg, binary_optarg, ternary_optarg @@ -1124,18 +1135,35 @@ def check_untested(funcdict, c_cls, p_cls): funcdict['untested'] = tuple(sorted(intersect-tested)) - #for key in ('untested', 'c_only', 'p_only'): - # s = 'Context' if c_cls == C.Context else 'Decimal' - # print("\n%s %s:\n%s" % (s, key, funcdict[key])) + # for key in ('untested', 'c_only', 'p_only'): + # s = 'Context' if c_cls == C.Context else 'Decimal' + # print("\n%s %s:\n%s" % (s, key, funcdict[key])) if __name__ == '__main__': - import time + parser = argparse.ArgumentParser(prog="deccheck.py") + + group = parser.add_mutually_exclusive_group() + group.add_argument('--short', dest='time', action="store_const", const='short', default='short', help="short test (default)") + group.add_argument('--medium', dest='time', action="store_const", const='medium', default='short', help="medium test (reasonable run time)") + group.add_argument('--long', dest='time', action="store_const", const='long', default='short', help="long test (long run time)") + group.add_argument('--all', dest='time', action="store_const", const='all', default='short', help="all tests (excessive run time)") + + group = parser.add_mutually_exclusive_group() + group.add_argument('--single', dest='single', nargs=1, default=False, metavar="TEST", help="run a single test") + group.add_argument('--multicore', dest='multicore', action="store_true", default=False, help="use all available cores") + + args = parser.parse_args() + assert args.single is False or args.multicore is False + if args.single: + args.single = args.single[0] + randseed = int(time.time()) random.seed(randseed) + # Set up the testspecs list. A testspec is simply a dictionary # that determines the amount of different contexts that 'test_method' # will generate. @@ -1168,17 +1196,17 @@ def check_untested(funcdict, c_cls, p_cls): {'prec': [34], 'expts': [(-6143, 6144)], 'clamp': 1, 'iter': None} ] - if '--medium' in sys.argv: + if args.time == 'medium': base['expts'].append(('rand', 'rand')) # 5 random precisions base['samples'] = 5 testspecs = [small] + ieee + [base] - if '--long' in sys.argv: + elif args.time == 'long': base['expts'].append(('rand', 'rand')) # 10 random precisions base['samples'] = 10 testspecs = [small] + ieee + [base] - elif '--all' in sys.argv: + elif args.time == 'all': base['expts'].append(('rand', 'rand')) # All precisions in [1, 100] base['samples'] = 100 @@ -1195,39 +1223,100 @@ def check_untested(funcdict, c_cls, p_cls): small['expts'] = [(-prec, prec)] testspecs = [small, rand_ieee, base] + check_untested(Functions, C.Decimal, P.Decimal) check_untested(ContextFunctions, C.Context, P.Context) - log("\n\nRandom seed: %d\n\n", randseed) + if args.multicore: + q = Queue() + elif args.single: + log("Random seed: %d", randseed) + else: + log("\n\nRandom seed: %d\n\n", randseed) + + + FOUND_METHOD = False + def do_single(method, f): + global FOUND_METHOD + if args.multicore: + q.put(method) + elif not args.single or args.single == method: + FOUND_METHOD = True + f() # Decimal methods: for method in Functions['unary'] + Functions['unary_ctx'] + \ Functions['unary_rnd_ctx']: - test_method(method, testspecs, test_unary) + do_single(method, lambda: test_method(method, testspecs, test_unary)) for method in Functions['binary'] + Functions['binary_ctx']: - test_method(method, testspecs, test_binary) + do_single(method, lambda: test_method(method, testspecs, test_binary)) for method in Functions['ternary'] + Functions['ternary_ctx']: - test_method(method, testspecs, test_ternary) + name = '__powmod__' if method == '__pow__' else method + do_single(name, lambda: test_method(method, testspecs, test_ternary)) - test_method('__format__', testspecs, test_format) - test_method('__round__', testspecs, test_round) - test_method('from_float', testspecs, test_from_float) - test_method('quantize', testspecs, test_quantize_api) + do_single('__format__', lambda: test_method('__format__', testspecs, test_format)) + do_single('__round__', lambda: test_method('__round__', testspecs, test_round)) + do_single('from_float', lambda: test_method('from_float', testspecs, test_from_float)) + do_single('quantize_api', lambda: test_method('quantize', testspecs, test_quantize_api)) # Context methods: for method in ContextFunctions['unary']: - test_method(method, testspecs, test_unary) + do_single(method, lambda: test_method(method, testspecs, test_unary)) for method in ContextFunctions['binary']: - test_method(method, testspecs, test_binary) + do_single(method, lambda: test_method(method, testspecs, test_binary)) for method in ContextFunctions['ternary']: - test_method(method, testspecs, test_ternary) + name = 'context.powmod' if method == 'context.power' else method + do_single(name, lambda: test_method(method, testspecs, test_ternary)) + + do_single('context.create_decimal_from_float', + lambda: test_method('context.create_decimal_from_float', + testspecs, test_from_float)) + + if args.multicore: + error = Event() + write_lock = Lock() - test_method('context.create_decimal_from_float', testspecs, test_from_float) + def write_output(out, returncode): + if returncode != 0: + error.set() + + with write_lock: + sys.stdout.buffer.write(out + b"\n") + sys.stdout.buffer.flush() + + def tfunc(): + while not error.is_set(): + try: + test = q.get(block=False, timeout=-1) + except Empty: + return + cmd = [sys.executable, "deccheck.py", "--%s" % args.time, "--single", test] + p = subprocess.Popen(cmd, stdout=PIPE, stderr=STDOUT) + out, _ = p.communicate() + write_output(out, p.returncode) - sys.exit(EXIT_STATUS) + N = os.cpu_count() + t = N * [None] + + for i in range(N): + t[i] = Thread(target=tfunc) + t[i].start() + + for i in range(N): + t[i].join() + + sys.exit(1 if error.is_set() else 0) + + elif args.single: + if not FOUND_METHOD: + log("\nerror: cannot find method \"%s\"" % args.single) + EXIT_STATUS = 1 + sys.exit(EXIT_STATUS) + else: + sys.exit(EXIT_STATUS) From webhook-mailer at python.org Mon Jun 8 14:04:52 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 08 Jun 2020 18:04:52 -0000 Subject: [Python-checkins] bpo-40854: PYTHONPLATLIBDIR env var added to 3.9 (GH-20735) Message-ID: https://github.com/python/cpython/commit/5edb83241f2ff899917e895092aca0216faf42d3 commit: 5edb83241f2ff899917e895092aca0216faf42d3 branch: master author: Victor Stinner committer: GitHub date: 2020-06-08T20:04:47+02:00 summary: bpo-40854: PYTHONPLATLIBDIR env var added to 3.9 (GH-20735) files: M Doc/c-api/init_config.rst M Doc/using/cmdline.rst diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index c51b157bbb33e..b7298ba825d3c 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -443,7 +443,7 @@ PyConfig by ``--with-platlibdir``, overrideable by the ``PYTHONPLATLIBDIR`` environment variable. - .. versionadded:: 3.10 + .. versionadded:: 3.9 .. c:member:: int buffered_stdio diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 3e0797279d6bf..f91ab020da5cf 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -543,7 +543,7 @@ conflict. If this is set to a non-empty string, it overrides the :data:`sys.platlibdir` value. - .. versionadded:: 3.10 + .. versionadded:: 3.9 .. envvar:: PYTHONSTARTUP From webhook-mailer at python.org Mon Jun 8 14:07:33 2020 From: webhook-mailer at python.org (Brett Cannon) Date: Mon, 08 Jun 2020 18:07:33 -0000 Subject: [Python-checkins] bpo-24914: mention Python supports multiple paradigms in the FAQ (#20658) Message-ID: https://github.com/python/cpython/commit/3ab3475c42c8ee5580f4ea1aeda73ebc8e5d5478 commit: 3ab3475c42c8ee5580f4ea1aeda73ebc8e5d5478 branch: master author: Brett Cannon committer: GitHub date: 2020-06-08T11:07:29-07:00 summary: bpo-24914: mention Python supports multiple paradigms in the FAQ (#20658) files: M Doc/faq/general.rst diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 3ef553e8acb43..70837341b1b33 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -17,12 +17,13 @@ What is Python? Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data -types, and classes. Python combines remarkable power with very clear syntax. -It has interfaces to many system calls and libraries, as well as to various -window systems, and is extensible in C or C++. It is also usable as an -extension language for applications that need a programmable interface. -Finally, Python is portable: it runs on many Unix variants, on the Mac, and on -Windows 2000 and later. +types, and classes. It supports multiple programming paradigms beyond +object-oriented programming, such as procedural and functional programming. +Python combines remarkable power with very clear syntax. It has interfaces to +many system calls and libraries, as well as to various window systems, and is +extensible in C or C++. It is also usable as an extension language for +applications that need a programmable interface. Finally, Python is portable: +it runs on many Unix variants including Linux and macOS, and on Windows. To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to Python `_ links to other From webhook-mailer at python.org Mon Jun 8 14:53:34 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 08 Jun 2020 18:53:34 -0000 Subject: [Python-checkins] bpo-24914: mention Python supports multiple paradigms in the FAQ (GH-20658) (GH-20738) Message-ID: https://github.com/python/cpython/commit/14073c509058f8efeb5ea7f7693bf84f410d24b7 commit: 14073c509058f8efeb5ea7f7693bf84f410d24b7 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-08T11:53:25-07:00 summary: bpo-24914: mention Python supports multiple paradigms in the FAQ (GH-20658) (GH-20738) (cherry picked from commit 3ab3475c42c8ee5580f4ea1aeda73ebc8e5d5478) Co-authored-by: Brett Cannon Co-authored-by: Brett Cannon files: M Doc/faq/general.rst diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 3ef553e8acb43..70837341b1b33 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -17,12 +17,13 @@ What is Python? Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data -types, and classes. Python combines remarkable power with very clear syntax. -It has interfaces to many system calls and libraries, as well as to various -window systems, and is extensible in C or C++. It is also usable as an -extension language for applications that need a programmable interface. -Finally, Python is portable: it runs on many Unix variants, on the Mac, and on -Windows 2000 and later. +types, and classes. It supports multiple programming paradigms beyond +object-oriented programming, such as procedural and functional programming. +Python combines remarkable power with very clear syntax. It has interfaces to +many system calls and libraries, as well as to various window systems, and is +extensible in C or C++. It is also usable as an extension language for +applications that need a programmable interface. Finally, Python is portable: +it runs on many Unix variants including Linux and macOS, and on Windows. To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to Python `_ links to other From webhook-mailer at python.org Mon Jun 8 15:38:48 2020 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 08 Jun 2020 19:38:48 -0000 Subject: [Python-checkins] Minor improvement to the namedtuple implementation (GH-20741) Message-ID: https://github.com/python/cpython/commit/0a40849eb99a0357113bff10434ec6605e3ae96b commit: 0a40849eb99a0357113bff10434ec6605e3ae96b branch: master author: Raymond Hettinger committer: GitHub date: 2020-06-08T12:38:41-07:00 summary: Minor improvement to the namedtuple implementation (GH-20741) * Cleaner way to build the arg list with a trailing comma when required * Fix appearance of __new__ in help() files: M Lib/collections/__init__.py diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 1e3b54ccf9cc9..6a06cc6a64f16 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -399,7 +399,9 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non # Variables used in the methods and docstrings field_names = tuple(map(_sys.intern, field_names)) num_fields = len(field_names) - arg_list = repr(field_names).replace("'", "")[1:-1] + arg_list = ', '.join(field_names) + if num_fields == 1: + arg_list += ',' repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' tuple_new = tuple.__new__ _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip @@ -410,6 +412,7 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non namespace = {'_tuple_new': tuple_new, '__builtins__': None, '__name__': f'namedtuple_{typename}'} __new__ = eval(s, namespace) + __new__.__name__ = '__new__' __new__.__doc__ = f'Create new instance of {typename}({arg_list})' if defaults is not None: __new__.__defaults__ = defaults From webhook-mailer at python.org Mon Jun 8 19:21:03 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:21:03 -0000 Subject: [Python-checkins] [3.8] Revert bpo-39576: Clarify the word size for the 32-bit build. (GH-20743) Message-ID: https://github.com/python/cpython/commit/706de4e5a4b21880c67f6b90e3a2147a258d6fc5 commit: 706de4e5a4b21880c67f6b90e3a2147a258d6fc5 branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-06-09T01:20:58+02:00 summary: [3.8] Revert bpo-39576: Clarify the word size for the 32-bit build. (GH-20743) This reverts commit c6ecd9c14081a787959e13df33e250102a658154. files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 3dda35fbd35db..f9421aba423ff 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2164,8 +2164,8 @@ RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys >>> - >>> # Maximum number of digits for a single operand using 500MB in 8-byte words - >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): + >>> # Maximum number of digits for a single operand using 500MB in 8 byte words + >>> # with 19 (9 for the 32-bit version) digits per word: >>> maxdigits = 19 * ((500 * 1024**2) // 8) >>> >>> # Check that this works: From webhook-mailer at python.org Mon Jun 8 19:22:08 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:22:08 -0000 Subject: [Python-checkins] [3.7] Revert bpo-39576: Clarify the word size for the 32-bit build. (GH-20744) Message-ID: https://github.com/python/cpython/commit/c0b79450bc9e93105799528151c48d25af8240a3 commit: c0b79450bc9e93105799528151c48d25af8240a3 branch: 3.7 author: Stefan Krah committer: GitHub date: 2020-06-09T01:22:03+02:00 summary: [3.7] Revert bpo-39576: Clarify the word size for the 32-bit build. (GH-20744) This reverts commit 24c570bbb82a7cb70576c253a73390accfa7ed78. files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 3dda35fbd35db..f9421aba423ff 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2164,8 +2164,8 @@ RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys >>> - >>> # Maximum number of digits for a single operand using 500MB in 8-byte words - >>> # with 19 digits per word (4-byte and 9 digits for the 32-bit build): + >>> # Maximum number of digits for a single operand using 500MB in 8 byte words + >>> # with 19 (9 for the 32-bit version) digits per word: >>> maxdigits = 19 * ((500 * 1024**2) // 8) >>> >>> # Check that this works: From webhook-mailer at python.org Mon Jun 8 19:33:16 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:33:16 -0000 Subject: [Python-checkins] [3.8] Revert bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-20745) Message-ID: https://github.com/python/cpython/commit/32c1fb07e6f2ded90e5dd24d4b46b7aa7a795d2e commit: 32c1fb07e6f2ded90e5dd24d4b46b7aa7a795d2e branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-06-09T01:33:08+02:00 summary: [3.8] Revert bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-20745) This reverts commit d6965ff026f35498e554bc964ef2be8f4d80eb7f. files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index f9421aba423ff..8169bd358c701 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2130,67 +2130,17 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. +arbitrary precision correctly-rounded decimal floating point arithmetic. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. +for very large numbers. However, to realize this performance gain, the +context needs to be set for unrounded calculations. -The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` -and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` -should always be 0 (the default). Setting :attr:`prec` requires some care. + >>> c = getcontext() + >>> c.prec = MAX_PREC + >>> c.Emax = MAX_EMAX + >>> c.Emin = MIN_EMIN -The easiest approach for trying out bignum arithmetic is to use the maximum -value for :attr:`prec` as well [#]_:: - - >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) - >>> x = Decimal(2) ** 256 - >>> x / 128 - Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') - - -For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and -the available memory will be insufficient:: - - >>> Decimal(1) / 3 - Traceback (most recent call last): - File "", line 1, in - MemoryError - -On systems with overallocation (e.g. Linux), a more sophisticated approach is to -adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of -RAM and expect 10 simultaneous operands using a maximum of 500MB each:: - - >>> import sys - >>> - >>> # Maximum number of digits for a single operand using 500MB in 8 byte words - >>> # with 19 (9 for the 32-bit version) digits per word: - >>> maxdigits = 19 * ((500 * 1024**2) // 8) - >>> - >>> # Check that this works: - >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) - >>> c.traps[Inexact] = True - >>> setcontext(c) - >>> - >>> # Fill the available precision with nines: - >>> x = Decimal(0).logical_invert() * 9 - >>> sys.getsizeof(x) - 524288112 - >>> x + 2 - Traceback (most recent call last): - File "", line 1, in - decimal.Inexact: [] - -In general (and especially on systems without overallocation), it is recommended -to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations -are expected to be exact. - - -.. [#] - .. versionadded:: 3.3 - -.. [#] - .. versionchanged:: 3.9 - This approach now works for all exact results except for non-integer powers. - Also backported to 3.7 and 3.8. +.. versionadded:: 3.3 \ No newline at end of file From webhook-mailer at python.org Mon Jun 8 19:34:07 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:34:07 -0000 Subject: [Python-checkins] [3.7] Revert bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-20746) Message-ID: https://github.com/python/cpython/commit/9bd891920a5186b7d02281ea9966225efa0ceba1 commit: 9bd891920a5186b7d02281ea9966225efa0ceba1 branch: 3.7 author: Stefan Krah committer: GitHub date: 2020-06-09T01:34:03+02:00 summary: [3.7] Revert bpo-39576: docs: set context for decimal arbitrary precision arithmetic (GH-20746) This reverts commit 00e45877e33d32bb61aa13a2033e3bba370bda4d. files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index f9421aba423ff..8169bd358c701 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2130,67 +2130,17 @@ Q. Is the CPython implementation fast for large numbers? A. Yes. In the CPython and PyPy3 implementations, the C/CFFI versions of the decimal module integrate the high speed `libmpdec `_ library for -arbitrary precision correctly-rounded decimal floating point arithmetic [#]_. +arbitrary precision correctly-rounded decimal floating point arithmetic. ``libmpdec`` uses `Karatsuba multiplication `_ for medium-sized numbers and the `Number Theoretic Transform `_ -for very large numbers. +for very large numbers. However, to realize this performance gain, the +context needs to be set for unrounded calculations. -The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` -and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` -should always be 0 (the default). Setting :attr:`prec` requires some care. + >>> c = getcontext() + >>> c.prec = MAX_PREC + >>> c.Emax = MAX_EMAX + >>> c.Emin = MIN_EMIN -The easiest approach for trying out bignum arithmetic is to use the maximum -value for :attr:`prec` as well [#]_:: - - >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) - >>> x = Decimal(2) ** 256 - >>> x / 128 - Decimal('904625697166532776746648320380374280103671755200316906558262375061821325312') - - -For inexact results, :attr:`MAX_PREC` is far too large on 64-bit platforms and -the available memory will be insufficient:: - - >>> Decimal(1) / 3 - Traceback (most recent call last): - File "", line 1, in - MemoryError - -On systems with overallocation (e.g. Linux), a more sophisticated approach is to -adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of -RAM and expect 10 simultaneous operands using a maximum of 500MB each:: - - >>> import sys - >>> - >>> # Maximum number of digits for a single operand using 500MB in 8 byte words - >>> # with 19 (9 for the 32-bit version) digits per word: - >>> maxdigits = 19 * ((500 * 1024**2) // 8) - >>> - >>> # Check that this works: - >>> c = Context(prec=maxdigits, Emax=MAX_EMAX, Emin=MIN_EMIN) - >>> c.traps[Inexact] = True - >>> setcontext(c) - >>> - >>> # Fill the available precision with nines: - >>> x = Decimal(0).logical_invert() * 9 - >>> sys.getsizeof(x) - 524288112 - >>> x + 2 - Traceback (most recent call last): - File "", line 1, in - decimal.Inexact: [] - -In general (and especially on systems without overallocation), it is recommended -to estimate even tighter bounds and set the :attr:`Inexact` trap if all calculations -are expected to be exact. - - -.. [#] - .. versionadded:: 3.3 - -.. [#] - .. versionchanged:: 3.9 - This approach now works for all exact results except for non-integer powers. - Also backported to 3.7 and 3.8. +.. versionadded:: 3.3 \ No newline at end of file From webhook-mailer at python.org Mon Jun 8 19:55:55 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:55:55 -0000 Subject: [Python-checkins] [3.7] Revert bpo-39576: Prevent memory error for overly optimistic precisions (GH-20748) Message-ID: https://github.com/python/cpython/commit/22faf6ad3bcc0ae478a9a3e2d8e35888d88d6ce8 commit: 22faf6ad3bcc0ae478a9a3e2d8e35888d88d6ce8 branch: 3.7 author: Stefan Krah committer: GitHub date: 2020-06-09T01:55:47+02:00 summary: [3.7] Revert bpo-39576: Prevent memory error for overly optimistic precisions (GH-20748) This reverts commit c6f95543b4832c3f0170179da39bcf99b40a7aa8. files: M Lib/test/test_decimal.py M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/tests/deccheck.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 0e9cd3095c85e..1f37b5372a3e7 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,41 +5476,6 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) - def test_maxcontext_exact_arith(self): - - # Make sure that exact operations do not raise MemoryError due - # to huge intermediate values when the context precision is very - # large. - - # The following functions fill the available precision and are - # therefore not suitable for large precisions (by design of the - # specification). - MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', - 'logical_and', 'logical_or', 'logical_xor', - 'next_toward', 'rotate', 'shift'] - - Decimal = C.Decimal - Context = C.Context - localcontext = C.localcontext - - # Here only some functions that are likely candidates for triggering a - # MemoryError are tested. deccheck.py has an exhaustive test. - maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) - with localcontext(maxcontext): - self.assertEqual(Decimal(0).exp(), 1) - self.assertEqual(Decimal(1).ln(), 0) - self.assertEqual(Decimal(1).log10(), 0) - self.assertEqual(Decimal(10**2).log10(), 2) - self.assertEqual(Decimal(10**223).log10(), 223) - self.assertEqual(Decimal(10**19).logb(), 19) - self.assertEqual(Decimal(4).sqrt(), 2) - self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) - self.assertEqual(divmod(Decimal(10), 3), (3, 1)) - self.assertEqual(Decimal(10) // 3, 3) - self.assertEqual(Decimal(4) / 2, 2) - self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) - - @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 0986edb576a10..bfa8bb343e60c 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -3781,43 +3781,6 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); - - if (*status & MPD_Malloc_error) { - /* Inexact quotients (the usual case) fill the entire context precision, - * which can lead to malloc() failures for very high precisions. Retry - * the operation with a lower precision in case the result is exact. - * - * We need an upper bound for the number of digits of a_coeff / b_coeff - * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest - * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable - * bound. - * - * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. - * The largest amount of digits is generated if b_coeff' is a power of 2 or - * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). - * - * We arrive at a total upper bound: - * - * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= - * a->digits + log2(b_coeff) = - * a->digits + log10(b_coeff) / log10(2) <= - * a->digits + b->digits * 4; - */ - uint32_t workstatus = 0; - mpd_context_t workctx = *ctx; - workctx.prec = a->digits + b->digits * 4; - if (workctx.prec >= ctx->prec) { - return; /* No point in retrying, keep the original error. */ - } - - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); - if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ - *status = 0; - return; - } - - mpd_seterror(q, *status, status); - } } /* Internal function. */ @@ -7739,9 +7702,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, /* END LIBMPDEC_ONLY */ /* Algorithm from decimal.py */ -static void -_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) +void +mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) { mpd_context_t maxcontext; MPD_NEW_STATIC(c,0,0,0,0); @@ -7873,40 +7836,6 @@ _mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, goto out; } -void -mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - _mpd_qsqrt(result, a, ctx, status); - - if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { - /* The above conditions can occur at very high context precisions - * if intermediate values get too large. Retry the operation with - * a lower context precision in case the result is exact. - * - * If the result is exact, an upper bound for the number of digits - * is the number of digits in the input. - * - * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 - */ - uint32_t workstatus = 0; - mpd_context_t workctx = *ctx; - workctx.prec = a->digits; - - if (workctx.prec >= ctx->prec) { - return; /* No point in repeating this, keep the original error. */ - } - - _mpd_qsqrt(result, a, &workctx, &workstatus); - if (workstatus == 0) { - *status = 0; - return; - } - - mpd_seterror(result, *status, status); - } -} - /******************************************************************************/ /* Base conversions */ diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 5cd5db5711426..f907531e1ffa5 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -125,12 +125,6 @@ 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') } -# Functions that set no context flags but whose result can differ depending -# on prec, Emin and Emax. -MaxContextSkip = ['is_normal', 'is_subnormal', 'logical_invert', 'next_minus', - 'next_plus', 'number_class', 'logical_and', 'logical_or', - 'logical_xor', 'next_toward', 'rotate', 'shift'] - # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', @@ -350,20 +344,6 @@ def __init__(self, funcname, operands): self.pex = RestrictedList() # Python exceptions for P.Decimal self.presults = RestrictedList() # P.Decimal results - # If the above results are exact, unrounded and not clamped, repeat - # the operation with a maxcontext to ensure that huge intermediate - # values do not cause a MemoryError. - self.with_maxcontext = False - self.maxcontext = context.c.copy() - self.maxcontext.prec = C.MAX_PREC - self.maxcontext.Emax = C.MAX_EMAX - self.maxcontext.Emin = C.MIN_EMIN - self.maxcontext.clear_flags() - - self.maxop = RestrictedList() # converted C.Decimal operands - self.maxex = RestrictedList() # Python exceptions for C.Decimal - self.maxresults = RestrictedList() # C.Decimal results - # ====================================================================== # SkipHandler: skip known discrepancies @@ -565,17 +545,13 @@ def function_as_string(t): if t.contextfunc: cargs = t.cop pargs = t.pop - maxargs = t.maxop cfunc = "c_func: %s(" % t.funcname pfunc = "p_func: %s(" % t.funcname - maxfunc = "max_func: %s(" % t.funcname else: cself, cargs = t.cop[0], t.cop[1:] pself, pargs = t.pop[0], t.pop[1:] - maxself, maxargs = t.maxop[0], t.maxop[1:] cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) - maxfunc = "max_func: %s.%s(" % (repr(maxself), t.funcname) err = cfunc for arg in cargs: @@ -589,14 +565,6 @@ def function_as_string(t): err = err.rstrip(", ") err += ")" - if t.with_maxcontext: - err += "\n" - err += maxfunc - for arg in maxargs: - err += "%s, " % repr(arg) - err = err.rstrip(", ") - err += ")" - return err def raise_error(t): @@ -609,24 +577,9 @@ def raise_error(t): err = "Error in %s:\n\n" % t.funcname err += "input operands: %s\n\n" % (t.op,) err += function_as_string(t) - - err += "\n\nc_result: %s\np_result: %s\n" % (t.cresults, t.presults) - if t.with_maxcontext: - err += "max_result: %s\n\n" % (t.maxresults) - else: - err += "\n" - - err += "c_exceptions: %s\np_exceptions: %s\n" % (t.cex, t.pex) - if t.with_maxcontext: - err += "max_exceptions: %s\n\n" % t.maxex - else: - err += "\n" - - err += "%s\n" % str(t.context) - if t.with_maxcontext: - err += "%s\n" % str(t.maxcontext) - else: - err += "\n" + err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) + err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) + err += "%s\n\n" % str(t.context) raise VerifyError(err) @@ -650,13 +603,6 @@ def raise_error(t): # are printed to stdout. # ====================================================================== -def all_nan(a): - if isinstance(a, C.Decimal): - return a.is_nan() - elif isinstance(a, tuple): - return all(all_nan(v) for v in a) - return False - def convert(t, convstr=True): """ t is the testset. At this stage the testset contains a tuple of operands t.op of various types. For decimal methods the first @@ -671,12 +617,10 @@ def convert(t, convstr=True): for i, op in enumerate(t.op): context.clear_status() - t.maxcontext.clear_flags() if op in RoundModes: t.cop.append(op) t.pop.append(op) - t.maxop.append(op) elif not t.contextfunc and i == 0 or \ convstr and isinstance(op, str): @@ -694,25 +638,11 @@ def convert(t, convstr=True): p = None pex = e.__class__ - try: - C.setcontext(t.maxcontext) - maxop = C.Decimal(op) - maxex = None - except (TypeError, ValueError, OverflowError) as e: - maxop = None - maxex = e.__class__ - finally: - C.setcontext(context.c) - t.cop.append(c) t.cex.append(cex) - t.pop.append(p) t.pex.append(pex) - t.maxop.append(maxop) - t.maxex.append(maxex) - if cex is pex: if str(c) != str(p) or not context.assert_eq_status(): raise_error(t) @@ -722,21 +652,14 @@ def convert(t, convstr=True): else: raise_error(t) - # The exceptions in the maxcontext operation can legitimately - # differ, only test that maxex implies cex: - if maxex is not None and cex is not maxex: - raise_error(t) - elif isinstance(op, Context): t.context = op t.cop.append(op.c) t.pop.append(op.p) - t.maxop.append(t.maxcontext) else: t.cop.append(op) t.pop.append(op) - t.maxop.append(op) return 1 @@ -750,7 +673,6 @@ def callfuncs(t): t.rc and t.rp are the results of the operation. """ context.clear_status() - t.maxcontext.clear_flags() try: if t.contextfunc: @@ -778,35 +700,6 @@ def callfuncs(t): t.rp = None t.pex.append(e.__class__) - # If the above results are exact, unrounded, normal etc., repeat the - # operation with a maxcontext to ensure that huge intermediate values - # do not cause a MemoryError. - if (t.funcname not in MaxContextSkip and - not context.c.flags[C.InvalidOperation] and - not context.c.flags[C.Inexact] and - not context.c.flags[C.Rounded] and - not context.c.flags[C.Subnormal] and - not context.c.flags[C.Clamped] and - not context.clamp and # results are padded to context.prec if context.clamp==1. - not any(isinstance(v, C.Context) for v in t.cop)): # another context is used. - t.with_maxcontext = True - try: - if t.contextfunc: - maxargs = t.maxop - t.rmax = getattr(t.maxcontext, t.funcname)(*maxargs) - else: - maxself = t.maxop[0] - maxargs = t.maxop[1:] - try: - C.setcontext(t.maxcontext) - t.rmax = getattr(maxself, t.funcname)(*maxargs) - finally: - C.setcontext(context.c) - t.maxex.append(None) - except (TypeError, ValueError, OverflowError, MemoryError) as e: - t.rmax = None - t.maxex.append(e.__class__) - def verify(t, stat): """ t is the testset. At this stage the testset contains the following tuples: @@ -821,9 +714,6 @@ def verify(t, stat): """ t.cresults.append(str(t.rc)) t.presults.append(str(t.rp)) - if t.with_maxcontext: - t.maxresults.append(str(t.rmax)) - if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): # General case: both results are Decimals. t.cresults.append(t.rc.to_eng_string()) @@ -835,12 +725,6 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) - if t.with_maxcontext and isinstance(t.rmax, C.Decimal): - t.maxresults.append(t.rmax.to_eng_string()) - t.maxresults.append(t.rmax.as_tuple()) - t.maxresults.append(str(t.rmax.imag)) - t.maxresults.append(str(t.rmax.real)) - nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: @@ -848,9 +732,6 @@ def verify(t, stat): if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): if t.rc != t.rp: raise_error(t) - if t.with_maxcontext and not isinstance(t.rmax, tuple): - if t.rmax != t.rc: - raise_error(t) stat[type(t.rc).__name__] += 1 # The return value lists must be equal. @@ -863,20 +744,6 @@ def verify(t, stat): if not t.context.assert_eq_status(): raise_error(t) - if t.with_maxcontext: - # NaN payloads etc. depend on precision and clamp. - if all_nan(t.rc) and all_nan(t.rmax): - return - # The return value lists must be equal. - if t.maxresults != t.cresults: - raise_error(t) - # The Python exception lists (TypeError, etc.) must be equal. - if t.maxex != t.cex: - raise_error(t) - # The context flags must be equal. - if t.maxcontext.flags != t.context.c.flags: - raise_error(t) - # ====================================================================== # Main test loops From webhook-mailer at python.org Mon Jun 8 19:57:15 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Mon, 08 Jun 2020 23:57:15 -0000 Subject: [Python-checkins] [3.8] Revert bpo-39576: Prevent memory error for overly optimistic precisions (GH-20747) Message-ID: https://github.com/python/cpython/commit/0f5a28f834bdac2da8a04597dc0fc5b71e50da9d commit: 0f5a28f834bdac2da8a04597dc0fc5b71e50da9d branch: 3.8 author: Stefan Krah committer: GitHub date: 2020-06-09T01:57:11+02:00 summary: [3.8] Revert bpo-39576: Prevent memory error for overly optimistic precisions (GH-20747) This reverts commit b6271025c640c228505dc9f194362a0c2ab81c61. files: M Lib/test/test_decimal.py M Modules/_decimal/libmpdec/mpdecimal.c M Modules/_decimal/tests/deccheck.py diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 0e9cd3095c85e..1f37b5372a3e7 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,41 +5476,6 @@ def __abs__(self): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) - def test_maxcontext_exact_arith(self): - - # Make sure that exact operations do not raise MemoryError due - # to huge intermediate values when the context precision is very - # large. - - # The following functions fill the available precision and are - # therefore not suitable for large precisions (by design of the - # specification). - MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', - 'logical_and', 'logical_or', 'logical_xor', - 'next_toward', 'rotate', 'shift'] - - Decimal = C.Decimal - Context = C.Context - localcontext = C.localcontext - - # Here only some functions that are likely candidates for triggering a - # MemoryError are tested. deccheck.py has an exhaustive test. - maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) - with localcontext(maxcontext): - self.assertEqual(Decimal(0).exp(), 1) - self.assertEqual(Decimal(1).ln(), 0) - self.assertEqual(Decimal(1).log10(), 0) - self.assertEqual(Decimal(10**2).log10(), 2) - self.assertEqual(Decimal(10**223).log10(), 223) - self.assertEqual(Decimal(10**19).logb(), 19) - self.assertEqual(Decimal(4).sqrt(), 2) - self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) - self.assertEqual(divmod(Decimal(10), 3), (3, 1)) - self.assertEqual(Decimal(10) // 3, 3) - self.assertEqual(Decimal(4) / 2, 2) - self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) - - @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 0986edb576a10..bfa8bb343e60c 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -3781,43 +3781,6 @@ mpd_qdiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { _mpd_qdiv(SET_IDEAL_EXP, q, a, b, ctx, status); - - if (*status & MPD_Malloc_error) { - /* Inexact quotients (the usual case) fill the entire context precision, - * which can lead to malloc() failures for very high precisions. Retry - * the operation with a lower precision in case the result is exact. - * - * We need an upper bound for the number of digits of a_coeff / b_coeff - * when the result is exact. If a_coeff' * 1 / b_coeff' is in lowest - * terms, then maxdigits(a_coeff') + maxdigits(1 / b_coeff') is a suitable - * bound. - * - * 1 / b_coeff' is exact iff b_coeff' exclusively has prime factors 2 or 5. - * The largest amount of digits is generated if b_coeff' is a power of 2 or - * a power of 5 and is less than or equal to log5(b_coeff') <= log2(b_coeff'). - * - * We arrive at a total upper bound: - * - * maxdigits(a_coeff') + maxdigits(1 / b_coeff') <= - * a->digits + log2(b_coeff) = - * a->digits + log10(b_coeff) / log10(2) <= - * a->digits + b->digits * 4; - */ - uint32_t workstatus = 0; - mpd_context_t workctx = *ctx; - workctx.prec = a->digits + b->digits * 4; - if (workctx.prec >= ctx->prec) { - return; /* No point in retrying, keep the original error. */ - } - - _mpd_qdiv(SET_IDEAL_EXP, q, a, b, &workctx, &workstatus); - if (workstatus == 0) { /* The result is exact, unrounded, normal etc. */ - *status = 0; - return; - } - - mpd_seterror(q, *status, status); - } } /* Internal function. */ @@ -7739,9 +7702,9 @@ mpd_qinvroot(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, /* END LIBMPDEC_ONLY */ /* Algorithm from decimal.py */ -static void -_mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) +void +mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, + uint32_t *status) { mpd_context_t maxcontext; MPD_NEW_STATIC(c,0,0,0,0); @@ -7873,40 +7836,6 @@ _mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, goto out; } -void -mpd_qsqrt(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, - uint32_t *status) -{ - _mpd_qsqrt(result, a, ctx, status); - - if (*status & (MPD_Malloc_error|MPD_Division_impossible)) { - /* The above conditions can occur at very high context precisions - * if intermediate values get too large. Retry the operation with - * a lower context precision in case the result is exact. - * - * If the result is exact, an upper bound for the number of digits - * is the number of digits in the input. - * - * NOTE: sqrt(40e9) = 2.0e+5 /\ digits(40e9) = digits(2.0e+5) = 2 - */ - uint32_t workstatus = 0; - mpd_context_t workctx = *ctx; - workctx.prec = a->digits; - - if (workctx.prec >= ctx->prec) { - return; /* No point in repeating this, keep the original error. */ - } - - _mpd_qsqrt(result, a, &workctx, &workstatus); - if (workstatus == 0) { - *status = 0; - return; - } - - mpd_seterror(result, *status, status); - } -} - /******************************************************************************/ /* Base conversions */ diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 5cd5db5711426..f907531e1ffa5 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -125,12 +125,6 @@ 'special': ('context.__reduce_ex__', 'context.create_decimal_from_float') } -# Functions that set no context flags but whose result can differ depending -# on prec, Emin and Emax. -MaxContextSkip = ['is_normal', 'is_subnormal', 'logical_invert', 'next_minus', - 'next_plus', 'number_class', 'logical_and', 'logical_or', - 'logical_xor', 'next_toward', 'rotate', 'shift'] - # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ '__ceil__', '__floor__', '__int__', '__trunc__', @@ -350,20 +344,6 @@ def __init__(self, funcname, operands): self.pex = RestrictedList() # Python exceptions for P.Decimal self.presults = RestrictedList() # P.Decimal results - # If the above results are exact, unrounded and not clamped, repeat - # the operation with a maxcontext to ensure that huge intermediate - # values do not cause a MemoryError. - self.with_maxcontext = False - self.maxcontext = context.c.copy() - self.maxcontext.prec = C.MAX_PREC - self.maxcontext.Emax = C.MAX_EMAX - self.maxcontext.Emin = C.MIN_EMIN - self.maxcontext.clear_flags() - - self.maxop = RestrictedList() # converted C.Decimal operands - self.maxex = RestrictedList() # Python exceptions for C.Decimal - self.maxresults = RestrictedList() # C.Decimal results - # ====================================================================== # SkipHandler: skip known discrepancies @@ -565,17 +545,13 @@ def function_as_string(t): if t.contextfunc: cargs = t.cop pargs = t.pop - maxargs = t.maxop cfunc = "c_func: %s(" % t.funcname pfunc = "p_func: %s(" % t.funcname - maxfunc = "max_func: %s(" % t.funcname else: cself, cargs = t.cop[0], t.cop[1:] pself, pargs = t.pop[0], t.pop[1:] - maxself, maxargs = t.maxop[0], t.maxop[1:] cfunc = "c_func: %s.%s(" % (repr(cself), t.funcname) pfunc = "p_func: %s.%s(" % (repr(pself), t.funcname) - maxfunc = "max_func: %s.%s(" % (repr(maxself), t.funcname) err = cfunc for arg in cargs: @@ -589,14 +565,6 @@ def function_as_string(t): err = err.rstrip(", ") err += ")" - if t.with_maxcontext: - err += "\n" - err += maxfunc - for arg in maxargs: - err += "%s, " % repr(arg) - err = err.rstrip(", ") - err += ")" - return err def raise_error(t): @@ -609,24 +577,9 @@ def raise_error(t): err = "Error in %s:\n\n" % t.funcname err += "input operands: %s\n\n" % (t.op,) err += function_as_string(t) - - err += "\n\nc_result: %s\np_result: %s\n" % (t.cresults, t.presults) - if t.with_maxcontext: - err += "max_result: %s\n\n" % (t.maxresults) - else: - err += "\n" - - err += "c_exceptions: %s\np_exceptions: %s\n" % (t.cex, t.pex) - if t.with_maxcontext: - err += "max_exceptions: %s\n\n" % t.maxex - else: - err += "\n" - - err += "%s\n" % str(t.context) - if t.with_maxcontext: - err += "%s\n" % str(t.maxcontext) - else: - err += "\n" + err += "\n\nc_result: %s\np_result: %s\n\n" % (t.cresults, t.presults) + err += "c_exceptions: %s\np_exceptions: %s\n\n" % (t.cex, t.pex) + err += "%s\n\n" % str(t.context) raise VerifyError(err) @@ -650,13 +603,6 @@ def raise_error(t): # are printed to stdout. # ====================================================================== -def all_nan(a): - if isinstance(a, C.Decimal): - return a.is_nan() - elif isinstance(a, tuple): - return all(all_nan(v) for v in a) - return False - def convert(t, convstr=True): """ t is the testset. At this stage the testset contains a tuple of operands t.op of various types. For decimal methods the first @@ -671,12 +617,10 @@ def convert(t, convstr=True): for i, op in enumerate(t.op): context.clear_status() - t.maxcontext.clear_flags() if op in RoundModes: t.cop.append(op) t.pop.append(op) - t.maxop.append(op) elif not t.contextfunc and i == 0 or \ convstr and isinstance(op, str): @@ -694,25 +638,11 @@ def convert(t, convstr=True): p = None pex = e.__class__ - try: - C.setcontext(t.maxcontext) - maxop = C.Decimal(op) - maxex = None - except (TypeError, ValueError, OverflowError) as e: - maxop = None - maxex = e.__class__ - finally: - C.setcontext(context.c) - t.cop.append(c) t.cex.append(cex) - t.pop.append(p) t.pex.append(pex) - t.maxop.append(maxop) - t.maxex.append(maxex) - if cex is pex: if str(c) != str(p) or not context.assert_eq_status(): raise_error(t) @@ -722,21 +652,14 @@ def convert(t, convstr=True): else: raise_error(t) - # The exceptions in the maxcontext operation can legitimately - # differ, only test that maxex implies cex: - if maxex is not None and cex is not maxex: - raise_error(t) - elif isinstance(op, Context): t.context = op t.cop.append(op.c) t.pop.append(op.p) - t.maxop.append(t.maxcontext) else: t.cop.append(op) t.pop.append(op) - t.maxop.append(op) return 1 @@ -750,7 +673,6 @@ def callfuncs(t): t.rc and t.rp are the results of the operation. """ context.clear_status() - t.maxcontext.clear_flags() try: if t.contextfunc: @@ -778,35 +700,6 @@ def callfuncs(t): t.rp = None t.pex.append(e.__class__) - # If the above results are exact, unrounded, normal etc., repeat the - # operation with a maxcontext to ensure that huge intermediate values - # do not cause a MemoryError. - if (t.funcname not in MaxContextSkip and - not context.c.flags[C.InvalidOperation] and - not context.c.flags[C.Inexact] and - not context.c.flags[C.Rounded] and - not context.c.flags[C.Subnormal] and - not context.c.flags[C.Clamped] and - not context.clamp and # results are padded to context.prec if context.clamp==1. - not any(isinstance(v, C.Context) for v in t.cop)): # another context is used. - t.with_maxcontext = True - try: - if t.contextfunc: - maxargs = t.maxop - t.rmax = getattr(t.maxcontext, t.funcname)(*maxargs) - else: - maxself = t.maxop[0] - maxargs = t.maxop[1:] - try: - C.setcontext(t.maxcontext) - t.rmax = getattr(maxself, t.funcname)(*maxargs) - finally: - C.setcontext(context.c) - t.maxex.append(None) - except (TypeError, ValueError, OverflowError, MemoryError) as e: - t.rmax = None - t.maxex.append(e.__class__) - def verify(t, stat): """ t is the testset. At this stage the testset contains the following tuples: @@ -821,9 +714,6 @@ def verify(t, stat): """ t.cresults.append(str(t.rc)) t.presults.append(str(t.rp)) - if t.with_maxcontext: - t.maxresults.append(str(t.rmax)) - if isinstance(t.rc, C.Decimal) and isinstance(t.rp, P.Decimal): # General case: both results are Decimals. t.cresults.append(t.rc.to_eng_string()) @@ -835,12 +725,6 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) - if t.with_maxcontext and isinstance(t.rmax, C.Decimal): - t.maxresults.append(t.rmax.to_eng_string()) - t.maxresults.append(t.rmax.as_tuple()) - t.maxresults.append(str(t.rmax.imag)) - t.maxresults.append(str(t.rmax.real)) - nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: @@ -848,9 +732,6 @@ def verify(t, stat): if not isinstance(t.rc, tuple) and not isinstance(t.rp, tuple): if t.rc != t.rp: raise_error(t) - if t.with_maxcontext and not isinstance(t.rmax, tuple): - if t.rmax != t.rc: - raise_error(t) stat[type(t.rc).__name__] += 1 # The return value lists must be equal. @@ -863,20 +744,6 @@ def verify(t, stat): if not t.context.assert_eq_status(): raise_error(t) - if t.with_maxcontext: - # NaN payloads etc. depend on precision and clamp. - if all_nan(t.rc) and all_nan(t.rmax): - return - # The return value lists must be equal. - if t.maxresults != t.cresults: - raise_error(t) - # The Python exception lists (TypeError, etc.) must be equal. - if t.maxex != t.cex: - raise_error(t) - # The context flags must be equal. - if t.maxcontext.flags != t.context.c.flags: - raise_error(t) - # ====================================================================== # Main test loops From webhook-mailer at python.org Tue Jun 9 04:27:53 2020 From: webhook-mailer at python.org (Stefan Krah) Date: Tue, 09 Jun 2020 08:27:53 -0000 Subject: [Python-checkins] Remove reference to 3.7 and 3.8 backports. (GH-20754) Message-ID: https://github.com/python/cpython/commit/323188360d61875bd68688ef41711bade298af50 commit: 323188360d61875bd68688ef41711bade298af50 branch: master author: Stefan Krah committer: GitHub date: 2020-06-09T10:27:45+02:00 summary: Remove reference to 3.7 and 3.8 backports. (GH-20754) files: M Doc/library/decimal.rst diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 69a20fca17898..38ad04177c5e8 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -2193,4 +2193,3 @@ are expected to be exact. .. [#] .. versionchanged:: 3.9 This approach now works for all exact results except for non-integer powers. - Also backported to 3.7 and 3.8. From webhook-mailer at python.org Tue Jun 9 08:39:10 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 09 Jun 2020 12:39:10 -0000 Subject: [Python-checkins] Add quotes to code to be a string Message-ID: https://github.com/python/cpython/commit/4b378acb97a575892c0e372a6bb0c17da1ccdf3e commit: 4b378acb97a575892c0e372a6bb0c17da1ccdf3e branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-09T05:39:01-07:00 summary: Add quotes to code to be a string files: A Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst M Lib/codeop.py M Lib/test/test_codeop.py diff --git a/Lib/codeop.py b/Lib/codeop.py index 3c37f35eb0250..3c2bb6083561e 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -57,6 +57,7 @@ """ import __future__ +import warnings _features = [getattr(__future__, fname) for fname in __future__.all_feature_names] @@ -83,15 +84,18 @@ def _maybe_compile(compiler, source, filename, symbol): except SyntaxError as err: pass - try: - code1 = compiler(source + "\n", filename, symbol) - except SyntaxError as e: - err1 = e - - try: - code2 = compiler(source + "\n\n", filename, symbol) - except SyntaxError as e: - err2 = e + # Suppress warnings after the first compile to avoid duplication. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + try: + code1 = compiler(source + "\n", filename, symbol) + except SyntaxError as e: + err1 = e + + try: + code2 = compiler(source + "\n\n", filename, symbol) + except SyntaxError as e: + err2 = e try: if code: diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 4d52d15fa0fb3..8e278b9b2311e 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -294,6 +294,11 @@ def test_filename(self): self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename, compile("a = 1\n", "def", 'single').co_filename) + def test_warning(self): + # Test that the warning is only returned once. + with support.check_warnings((".*invalid", DeprecationWarning)) as w: + compile_command("'\e'") + self.assertEqual(len(w.warnings), 1) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst new file mode 100644 index 0000000000000..532b809b77eed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-06-04-16-25-15.bpo-40807.yYyLWx.rst @@ -0,0 +1,2 @@ +Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). +from from emitting each warning three times. From webhook-mailer at python.org Tue Jun 9 09:32:52 2020 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 09 Jun 2020 13:32:52 -0000 Subject: [Python-checkins] bpo-40684: Fix make install for platlibdir=lib64 (GH-20736) Message-ID: https://github.com/python/cpython/commit/51ae31e5b93b986e57a7e18e25f981a6ffcdefb7 commit: 51ae31e5b93b986e57a7e18e25f981a6ffcdefb7 branch: master author: Victor Stinner committer: GitHub date: 2020-06-09T15:32:43+02:00 summary: bpo-40684: Fix make install for platlibdir=lib64 (GH-20736) "make install" now uses the PLATLIBDIR variable for the destination lib-dynload/ directory when ./configure --with-platlibdir is used. Update --with-platlibdir comment in configure. files: A Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst M Makefile.pre.in M configure M configure.ac diff --git a/Makefile.pre.in b/Makefile.pre.in index 9cb7a23eea582..7c16d2905fbf4 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -148,7 +148,7 @@ SCRIPTDIR= $(prefix)/$(PLATLIBDIR) ABIFLAGS= @ABIFLAGS@ # Detailed destination directories -BINLIBDEST= $(LIBDIR)/python$(VERSION) +BINLIBDEST= @BINLIBDEST@ LIBDEST= $(SCRIPTDIR)/python$(VERSION) INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION) CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION) diff --git a/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst b/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst new file mode 100644 index 0000000000000..0495e5e413622 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2020-06-08-19-57-05.bpo-40684.WIY2-i.rst @@ -0,0 +1,2 @@ +``make install`` now uses the ``PLATLIBDIR`` variable for the destination +``lib-dynload/`` directory when ``./configure --with-platlibdir`` is used. diff --git a/configure b/configure index 1124412dce475..139c2bf7de132 100755 --- a/configure +++ b/configure @@ -632,6 +632,7 @@ THREADHEADERS LIBPL PY_ENABLE_SHARED PLATLIBDIR +BINLIBDEST LIBPYTHON EXT_SUFFIX ALT_SOABI @@ -15334,7 +15335,11 @@ else fi -# Check for --with-libdir-name + +BINLIBDEST='$(LIBDIR)/python$(VERSION)' + + +# Check for --with-platlibdir # /usr/$LIDIRNAME/python$VERSION PLATLIBDIR="lib" @@ -15353,6 +15358,7 @@ then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } PLATLIBDIR="$withval" + BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)' else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } diff --git a/configure.ac b/configure.ac index 84d1f00983f89..30856c8b6883d 100644 --- a/configure.ac +++ b/configure.ac @@ -4770,7 +4770,11 @@ else fi -# Check for --with-libdir-name +AC_SUBST(BINLIBDEST) +BINLIBDEST='$(LIBDIR)/python$(VERSION)' + + +# Check for --with-platlibdir # /usr/$LIDIRNAME/python$VERSION AC_SUBST(PLATLIBDIR) PLATLIBDIR="lib" @@ -4787,6 +4791,7 @@ if test -n "$withval" -a "$withval" != yes -a "$withval" != no then AC_MSG_RESULT(yes) PLATLIBDIR="$withval" + BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)' else AC_MSG_RESULT(no) fi], From webhook-mailer at python.org Tue Jun 9 11:33:51 2020 From: webhook-mailer at python.org (Dong-hee Na) Date: Tue, 09 Jun 2020 15:33:51 -0000 Subject: [Python-checkins] Remove usesless function from csv module (GH-20762) Message-ID: https://github.com/python/cpython/commit/0383be4666905f9e24ca791afda845a7686b3fe3 commit: 0383be4666905f9e24ca791afda845a7686b3fe3 branch: master author: Dong-hee Na committer: GitHub date: 2020-06-10T00:33:43+09:00 summary: Remove usesless function from csv module (GH-20762) files: M Modules/_csv.c diff --git a/Modules/_csv.c b/Modules/_csv.c index 7e44419c0876b..2d4247740eb29 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -146,13 +146,6 @@ get_dialect_from_registry(PyObject * name_obj) return dialect_obj; } -static PyObject * -get_string(PyObject *str) -{ - Py_XINCREF(str); - return str; -} - static PyObject * get_nullchar_as_None(Py_UCS4 c) { @@ -166,7 +159,8 @@ get_nullchar_as_None(Py_UCS4 c) static PyObject * Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) { - return get_string(self->lineterminator); + Py_XINCREF(self->lineterminator); + return self->lineterminator; } static PyObject * From webhook-mailer at python.org Tue Jun 9 21:26:20 2020 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 10 Jun 2020 01:26:20 -0000 Subject: [Python-checkins] [3.8] bpo-34003: Re-add versionchanged entry in csv docs (GH-20657) (GH-20771) Message-ID: https://github.com/python/cpython/commit/663836e1179ea79eac12e55670af7e89a531a060 commit: 663836e1179ea79eac12e55670af7e89a531a060 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2020-06-09T18:26:16-07:00 summary: [3.8] bpo-34003: Re-add versionchanged entry in csv docs (GH-20657) (GH-20771) Follow-up to GH-8014 (cherry picked from commit 7aed0524d4129766a6032326949ef7f91f6f6dfc) Co-authored-by: ?ric Araujo Automerge-Triggered-By: @merwok files: M Doc/library/csv.rst diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 61d39828e0194..7a72c26d5bade 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -167,6 +167,9 @@ The :mod:`csv` module defines the following classes: All other optional or keyword arguments are passed to the underlying :class:`reader` instance. + .. versionchanged:: 3.6 + Returned rows are now of type :class:`OrderedDict`. + .. versionchanged:: 3.8 Returned rows are now of type :class:`dict`. From webhook-mailer at python.org Tue Jun 9 23:53:31 2020 From: webhook-mailer at python.org (Joannah Nanjekye) Date: Wed, 10 Jun 2020 03:53:31 -0000 Subject: [Python-checkins] bpo-32604: Recommit "bpo-32604: PEP 554 for use in test suite (GH-19985)" (GH-20611) Message-ID: https://github.com/python/cpython/commit/bae872f1fe9b3a0d3e3b8800a2ac8d6b440d6e4d commit: bae872f1fe9b3a0d3e3b8800a2ac8d6b440d6e4d branch: master author: Joannah Nanjekye <33177550+nanjekyejoannah at users.noreply.github.com> committer: GitHub date: 2020-06-10T00:53:23-03:00 summary: bpo-32604: Recommit "bpo-32604: PEP 554 for use in test suite (GH-19985)" (GH-20611) * PEP 554 for use in test suite * ?? Added by blurb_it. * Fix space * Add doc to doc tree * Move to modules doc tree * Fix suspicious doc errors * Fix test__all * Docs docs docs * Support isolated and fix wait * Fix white space * Remove undefined from __all__ * Fix recv and add exceptions * Remove unused exceptions, fix pep 8 formatting errors and fix _NOT_SET in recv_nowait() * Update Lib/test/support/interpreters.py Co-authored-by: Pablo Galindo * Remove documentation (module is for internal use) Co-authored-by: nanjekyejoannah Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Lib/test/support/interpreters.py A Lib/test/test_interpreters.py A Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst diff --git a/Lib/test/support/interpreters.py b/Lib/test/support/interpreters.py new file mode 100644 index 0000000000000..09508e1bbeca0 --- /dev/null +++ b/Lib/test/support/interpreters.py @@ -0,0 +1,183 @@ +"""Subinterpreters High Level Module.""" + +import _xxsubinterpreters as _interpreters + +# aliases: +from _xxsubinterpreters import ( + ChannelError, ChannelNotFoundError, ChannelEmptyError, + is_shareable, +) + + +__all__ = [ + 'Interpreter', 'get_current', 'get_main', 'create', 'list_all', + 'SendChannel', 'RecvChannel', + 'create_channel', 'list_all_channels', 'is_shareable', + 'ChannelError', 'ChannelNotFoundError', + 'ChannelEmptyError', + ] + + +def create(*, isolated=True): + """ + Initialize a new (idle) Python interpreter. + """ + id = _interpreters.create(isolated=isolated) + return Interpreter(id, isolated=isolated) + + +def list_all(): + """ + Get all existing interpreters. + """ + return [Interpreter(id) for id in + _interpreters.list_all()] + + +def get_current(): + """ + Get the currently running interpreter. + """ + id = _interpreters.get_current() + return Interpreter(id) + + +def get_main(): + """ + Get the main interpreter. + """ + id = _interpreters.get_main() + return Interpreter(id) + + +class Interpreter: + """ + The Interpreter object represents + a single interpreter. + """ + + def __init__(self, id, *, isolated=None): + self._id = id + self._isolated = isolated + + @property + def id(self): + return self._id + + @property + def isolated(self): + if self._isolated is None: + self._isolated = _interpreters.is_isolated(self._id) + return self._isolated + + def is_running(self): + """ + Return whether or not the identified + interpreter is running. + """ + return _interpreters.is_running(self._id) + + def close(self): + """ + Finalize and destroy the interpreter. + + Attempting to destroy the current + interpreter results in a RuntimeError. + """ + return _interpreters.destroy(self._id) + + def run(self, src_str, /, *, channels=None): + """ + Run the given source code in the interpreter. + This blocks the current Python thread until done. + """ + _interpreters.run_string(self._id, src_str) + + +def create_channel(): + """ + Create a new channel for passing data between + interpreters. + """ + + cid = _interpreters.channel_create() + return (RecvChannel(cid), SendChannel(cid)) + + +def list_all_channels(): + """ + Get all open channels. + """ + return [(RecvChannel(cid), SendChannel(cid)) + for cid in _interpreters.channel_list_all()] + + +_NOT_SET = object() + + +class RecvChannel: + """ + The RecvChannel object represents + a receiving channel. + """ + + def __init__(self, id): + self._id = id + + def recv(self, *, _delay=10 / 1000): # 10 milliseconds + """ + Get the next object from the channel, + and wait if none have been sent. + Associate the interpreter with the channel. + """ + import time + sentinel = object() + obj = _interpreters.channel_recv(self._id, sentinel) + while obj is sentinel: + time.sleep(_delay) + obj = _interpreters.channel_recv(self._id, sentinel) + return obj + + def recv_nowait(self, default=_NOT_SET): + """ + Like recv(), but return the default + instead of waiting. + + This function is blocked by a missing low-level + implementation of channel_recv_wait(). + """ + if default is _NOT_SET: + return _interpreters.channel_recv(self._id) + else: + return _interpreters.channel_recv(self._id, default) + + +class SendChannel: + """ + The SendChannel object represents + a sending channel. + """ + + def __init__(self, id): + self._id = id + + def send(self, obj): + """ + Send the object (i.e. its data) to the receiving + end of the channel and wait. Associate the interpreter + with the channel. + """ + import time + _interpreters.channel_send(self._id, obj) + time.sleep(2) + + def send_nowait(self, obj): + """ + Like send(), but return False if not received. + + This function is blocked by a missing low-level + implementation of channel_send_wait(). + """ + + _interpreters.channel_send(self._id, obj) + return False diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py new file mode 100644 index 0000000000000..3451a4c8759d8 --- /dev/null +++ b/Lib/test/test_interpreters.py @@ -0,0 +1,535 @@ +import contextlib +import os +import threading +from textwrap import dedent +import unittest +import time + +import _xxsubinterpreters as _interpreters +from test.support import interpreters + + +def _captured_script(script): + r, w = os.pipe() + indented = script.replace('\n', '\n ') + wrapped = dedent(f""" + import contextlib + with open({w}, 'w') as spipe: + with contextlib.redirect_stdout(spipe): + {indented} + """) + return wrapped, open(r) + + +def clean_up_interpreters(): + for interp in interpreters.list_all(): + if interp.id == 0: # main + continue + try: + interp.close() + except RuntimeError: + pass # already destroyed + + +def _run_output(interp, request, shared=None): + script, rpipe = _captured_script(request) + with rpipe: + interp.run(script) + return rpipe.read() + + + at contextlib.contextmanager +def _running(interp): + r, w = os.pipe() + def run(): + interp.run(dedent(f""" + # wait for "signal" + with open({r}) as rpipe: + rpipe.read() + """)) + + t = threading.Thread(target=run) + t.start() + + yield + + with open(w, 'w') as spipe: + spipe.write('done') + t.join() + + +class TestBase(unittest.TestCase): + + def tearDown(self): + clean_up_interpreters() + + +class CreateTests(TestBase): + + def test_in_main(self): + interp = interpreters.create() + lst = interpreters.list_all() + self.assertEqual(interp.id, lst[1].id) + + def test_in_thread(self): + lock = threading.Lock() + id = None + interp = interpreters.create() + lst = interpreters.list_all() + def f(): + nonlocal id + id = interp.id + lock.acquire() + lock.release() + + t = threading.Thread(target=f) + with lock: + t.start() + t.join() + self.assertEqual(interp.id, lst[1].id) + + def test_in_subinterpreter(self): + main, = interpreters.list_all() + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + interp = interpreters.create() + print(interp) + """)) + interp2 = out.strip() + + self.assertEqual(len(set(interpreters.list_all())), len({main, interp, interp2})) + + def test_after_destroy_all(self): + before = set(interpreters.list_all()) + # Create 3 subinterpreters. + interp_lst = [] + for _ in range(3): + interps = interpreters.create() + interp_lst.append(interps) + # Now destroy them. + for interp in interp_lst: + interp.close() + # Finally, create another. + interp = interpreters.create() + self.assertEqual(len(set(interpreters.list_all())), len(before | {interp})) + + def test_after_destroy_some(self): + before = set(interpreters.list_all()) + # Create 3 subinterpreters. + interp1 = interpreters.create() + interp2 = interpreters.create() + interp3 = interpreters.create() + # Now destroy 2 of them. + interp1.close() + interp2.close() + # Finally, create another. + interp = interpreters.create() + self.assertEqual(len(set(interpreters.list_all())), len(before | {interp3, interp})) + + +class GetCurrentTests(TestBase): + + def test_main(self): + main_interp_id = _interpreters.get_main() + cur_interp_id = interpreters.get_current().id + self.assertEqual(cur_interp_id, main_interp_id) + + def test_subinterpreter(self): + main = _interpreters.get_main() + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + cur = interpreters.get_current() + print(cur) + """)) + cur = out.strip() + self.assertNotEqual(cur, main) + + +class ListAllTests(TestBase): + + def test_initial(self): + interps = interpreters.list_all() + self.assertEqual(1, len(interps)) + + def test_after_creating(self): + main = interpreters.get_current() + first = interpreters.create() + second = interpreters.create() + + ids = [] + for interp in interpreters.list_all(): + ids.append(interp.id) + + self.assertEqual(ids, [main.id, first.id, second.id]) + + def test_after_destroying(self): + main = interpreters.get_current() + first = interpreters.create() + second = interpreters.create() + first.close() + + ids = [] + for interp in interpreters.list_all(): + ids.append(interp.id) + + self.assertEqual(ids, [main.id, second.id]) + + +class TestInterpreterId(TestBase): + + def test_in_main(self): + main = interpreters.get_current() + self.assertEqual(0, main.id) + + def test_with_custom_num(self): + interp = interpreters.Interpreter(1) + self.assertEqual(1, interp.id) + + def test_for_readonly_property(self): + interp = interpreters.Interpreter(1) + with self.assertRaises(AttributeError): + interp.id = 2 + + +class TestInterpreterIsRunning(TestBase): + + def test_main(self): + main = interpreters.get_current() + self.assertTrue(main.is_running()) + + def test_subinterpreter(self): + interp = interpreters.create() + self.assertFalse(interp.is_running()) + + with _running(interp): + self.assertTrue(interp.is_running()) + self.assertFalse(interp.is_running()) + + def test_from_subinterpreter(self): + interp = interpreters.create() + out = _run_output(interp, dedent(f""" + import _xxsubinterpreters as _interpreters + if _interpreters.is_running({interp.id}): + print(True) + else: + print(False) + """)) + self.assertEqual(out.strip(), 'True') + + def test_already_destroyed(self): + interp = interpreters.create() + interp.close() + with self.assertRaises(RuntimeError): + interp.is_running() + + +class TestInterpreterDestroy(TestBase): + + def test_basic(self): + interp1 = interpreters.create() + interp2 = interpreters.create() + interp3 = interpreters.create() + self.assertEqual(4, len(interpreters.list_all())) + interp2.close() + self.assertEqual(3, len(interpreters.list_all())) + + def test_all(self): + before = set(interpreters.list_all()) + interps = set() + for _ in range(3): + interp = interpreters.create() + interps.add(interp) + self.assertEqual(len(set(interpreters.list_all())), len(before | interps)) + for interp in interps: + interp.close() + self.assertEqual(len(set(interpreters.list_all())), len(before)) + + def test_main(self): + main, = interpreters.list_all() + with self.assertRaises(RuntimeError): + main.close() + + def f(): + with self.assertRaises(RuntimeError): + main.close() + + t = threading.Thread(target=f) + t.start() + t.join() + + def test_already_destroyed(self): + interp = interpreters.create() + interp.close() + with self.assertRaises(RuntimeError): + interp.close() + + def test_from_current(self): + main, = interpreters.list_all() + interp = interpreters.create() + script = dedent(f""" + from test.support import interpreters + try: + main = interpreters.get_current() + main.close() + except RuntimeError: + pass + """) + + interp.run(script) + self.assertEqual(len(set(interpreters.list_all())), len({main, interp})) + + def test_from_sibling(self): + main, = interpreters.list_all() + interp1 = interpreters.create() + script = dedent(f""" + from test.support import interpreters + interp2 = interpreters.create() + interp2.close() + """) + interp1.run(script) + + self.assertEqual(len(set(interpreters.list_all())), len({main, interp1})) + + def test_from_other_thread(self): + interp = interpreters.create() + def f(): + interp.close() + + t = threading.Thread(target=f) + t.start() + t.join() + + def test_still_running(self): + main, = interpreters.list_all() + interp = interpreters.create() + with _running(interp): + with self.assertRaises(RuntimeError): + interp.close() + self.assertTrue(interp.is_running()) + + +class TestInterpreterRun(TestBase): + + SCRIPT = dedent(""" + with open('{}', 'w') as out: + out.write('{}') + """) + FILENAME = 'spam' + + def setUp(self): + super().setUp() + self.interp = interpreters.create() + self._fs = None + + def tearDown(self): + if self._fs is not None: + self._fs.close() + super().tearDown() + + @property + def fs(self): + if self._fs is None: + self._fs = FSFixture(self) + return self._fs + + def test_success(self): + script, file = _captured_script('print("it worked!", end="")') + with file: + self.interp.run(script) + out = file.read() + + self.assertEqual(out, 'it worked!') + + def test_in_thread(self): + script, file = _captured_script('print("it worked!", end="")') + with file: + def f(): + self.interp.run(script) + + t = threading.Thread(target=f) + t.start() + t.join() + out = file.read() + + self.assertEqual(out, 'it worked!') + + @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + def test_fork(self): + import tempfile + with tempfile.NamedTemporaryFile('w+') as file: + file.write('') + file.flush() + + expected = 'spam spam spam spam spam' + script = dedent(f""" + import os + try: + os.fork() + except RuntimeError: + with open('{file.name}', 'w') as out: + out.write('{expected}') + """) + self.interp.run(script) + + file.seek(0) + content = file.read() + self.assertEqual(content, expected) + + def test_already_running(self): + with _running(self.interp): + with self.assertRaises(RuntimeError): + self.interp.run('print("spam")') + + def test_bad_script(self): + with self.assertRaises(TypeError): + self.interp.run(10) + + def test_bytes_for_script(self): + with self.assertRaises(TypeError): + self.interp.run(b'print("spam")') + + +class TestIsShareable(TestBase): + + def test_default_shareables(self): + shareables = [ + # singletons + None, + # builtin objects + b'spam', + 'spam', + 10, + -10, + ] + for obj in shareables: + with self.subTest(obj): + self.assertTrue( + interpreters.is_shareable(obj)) + + def test_not_shareable(self): + class Cheese: + def __init__(self, name): + self.name = name + def __str__(self): + return self.name + + class SubBytes(bytes): + """A subclass of a shareable type.""" + + not_shareables = [ + # singletons + True, + False, + NotImplemented, + ..., + # builtin types and objects + type, + object, + object(), + Exception(), + 100.0, + # user-defined types and objects + Cheese, + Cheese('Wensleydale'), + SubBytes(b'spam'), + ] + for obj in not_shareables: + with self.subTest(repr(obj)): + self.assertFalse( + interpreters.is_shareable(obj)) + + +class TestChannel(TestBase): + + def test_create_cid(self): + r, s = interpreters.create_channel() + self.assertIsInstance(r, interpreters.RecvChannel) + self.assertIsInstance(s, interpreters.SendChannel) + + def test_sequential_ids(self): + before = interpreters.list_all_channels() + channels1 = interpreters.create_channel() + channels2 = interpreters.create_channel() + channels3 = interpreters.create_channel() + after = interpreters.list_all_channels() + + self.assertEqual(len(set(after) - set(before)), + len({channels1, channels2, channels3})) + + +class TestSendRecv(TestBase): + + def test_send_recv_main(self): + r, s = interpreters.create_channel() + orig = b'spam' + s.send(orig) + obj = r.recv() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_same_interpreter(self): + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + r, s = interpreters.create_channel() + orig = b'spam' + s.send(orig) + obj = r.recv() + assert obj is not orig + assert obj == orig + """)) + + def test_send_recv_different_threads(self): + r, s = interpreters.create_channel() + + def f(): + while True: + try: + obj = r.recv() + break + except interpreters.ChannelEmptyError: + time.sleep(0.1) + s.send(obj) + t = threading.Thread(target=f) + t.start() + + s.send(b'spam') + t.join() + obj = r.recv() + + self.assertEqual(obj, b'spam') + + def test_send_recv_nowait_main(self): + r, s = interpreters.create_channel() + orig = b'spam' + s.send(orig) + obj = r.recv_nowait() + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_nowait_same_interpreter(self): + interp = interpreters.create() + out = _run_output(interp, dedent(""" + from test.support import interpreters + r, s = interpreters.create_channel() + orig = b'spam' + s.send(orig) + obj = r.recv_nowait() + assert obj is not orig + assert obj == orig + """)) + + r, s = interpreters.create_channel() + + def f(): + while True: + try: + obj = r.recv_nowait() + break + except _interpreters.ChannelEmptyError: + time.sleep(0.1) + s.send(obj) diff --git a/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst b/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst new file mode 100644 index 0000000000000..1129cd7649b96 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-07-22-00-12.bpo-39881.E1xsNv.rst @@ -0,0 +1,2 @@ +PEP 554 for use in the test suite. +(Patch By Joannah Nanjekye) \ No newline at end of file From webhook-mailer at python.org Wed Jun 10 01:57:09 2020 From: webhook-mailer at python.org (Dennis Sweeney) Date: Wed, 10 Jun 2020 05:57:09 -0000 Subject: [Python-checkins] bpo-40889: Optimize dict.items() ^ dict.items() (GH-20718) Message-ID: https://github.com/python/cpython/commit/07d81128124f2b574808e33267c38b104b42ae2a commit: 07d81128124f2b574808e33267c38b104b42ae2a branch: master author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: GitHub date: 2020-06-10T14:56:56+09:00 summary: bpo-40889: Optimize dict.items() ^ dict.items() (GH-20718) files: A Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst M Lib/test/test_dict.py M Objects/dictobject.c diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 6b8596fff6a9f..5c08810f879b1 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -697,6 +697,16 @@ def test_dictview_set_operations_on_items(self): self.assertEqual(k1 ^ k2, {(3,3)}) self.assertEqual(k1 ^ k3, {(1,1), (2,2), (4,4)}) + def test_items_symmetric_difference(self): + rr = random.randrange + for _ in range(100): + left = {x:rr(3) for x in range(20) if rr(2)} + right = {x:rr(3) for x in range(20) if rr(2)} + with self.subTest(left=left, right=right): + expected = set(left.items()) ^ set(right.items()) + actual = left.items() ^ right.items() + self.assertEqual(actual, expected) + def test_dictview_mixed_set_operations(self): # Just a few for .keys() self.assertTrue({1:1}.keys() == {1}) diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst new file mode 100644 index 0000000000000..0ab1a261e3e6e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-08-22-46-33.bpo-40889.vIBl-W.rst @@ -0,0 +1 @@ +Improved the performance of symmetric difference operations on dictionary item views. Patch by Dennis Sweeney. \ No newline at end of file diff --git a/Objects/dictobject.c b/Objects/dictobject.c index c4d5da51f3193..1bb8cfdab2b68 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4409,9 +4409,99 @@ dictviews_or(PyObject* self, PyObject *other) return result; } +static PyObject * +dictitems_xor(PyObject *self, PyObject *other) +{ + assert(PyDictItems_Check(self)); + assert(PyDictItems_Check(other)); + PyObject *d1 = (PyObject *)((_PyDictViewObject *)self)->dv_dict; + PyObject *d2 = (PyObject *)((_PyDictViewObject *)other)->dv_dict; + + PyObject *temp_dict = PyDict_Copy(d1); + if (temp_dict == NULL) { + return NULL; + } + PyObject *result_set = PySet_New(NULL); + if (result_set == NULL) { + Py_CLEAR(temp_dict); + return NULL; + } + + PyObject *key = NULL, *val1 = NULL, *val2 = NULL; + Py_ssize_t pos = 0; + Py_hash_t hash; + + while (_PyDict_Next(d2, &pos, &key, &val2, &hash)) { + Py_INCREF(key); + Py_INCREF(val2); + val1 = _PyDict_GetItem_KnownHash(temp_dict, key, hash); + + int to_delete; + if (val1 == NULL) { + if (PyErr_Occurred()) { + goto error; + } + to_delete = 0; + } + else { + Py_INCREF(val1); + to_delete = PyObject_RichCompareBool(val1, val2, Py_EQ); + if (to_delete < 0) { + goto error; + } + } + + if (to_delete) { + if (_PyDict_DelItem_KnownHash(temp_dict, key, hash) < 0) { + goto error; + } + } + else { + PyObject *pair = PyTuple_Pack(2, key, val2); + if (pair == NULL) { + goto error; + } + if (PySet_Add(result_set, pair) < 0) { + Py_DECREF(pair); + goto error; + } + Py_DECREF(pair); + } + Py_DECREF(key); + Py_XDECREF(val1); + Py_DECREF(val2); + } + key = val1 = val2 = NULL; + + _Py_IDENTIFIER(items); + PyObject *remaining_pairs = _PyObject_CallMethodIdNoArgs(temp_dict, + &PyId_items); + if (remaining_pairs == NULL) { + goto error; + } + if (_PySet_Update(result_set, remaining_pairs) < 0) { + Py_DECREF(remaining_pairs); + goto error; + } + Py_DECREF(temp_dict); + Py_DECREF(remaining_pairs); + return result_set; + +error: + Py_XDECREF(temp_dict); + Py_XDECREF(result_set); + Py_XDECREF(key); + Py_XDECREF(val1); + Py_XDECREF(val2); + return NULL; +} + static PyObject* dictviews_xor(PyObject* self, PyObject *other) { + if (PyDictItems_Check(self) && PyDictItems_Check(other)) { + return dictitems_xor(self, other); + } PyObject *result = dictviews_to_set(self); if (result == NULL) { return NULL; From webhook-mailer at python.org Wed Jun 10 08:29:07 2020 From: webhook-mailer at python.org (Hai Shi) Date: Wed, 10 Jun 2020 12:29:07 -0000 Subject: [Python-checkins] bpo-40275: Add os_helper submodule in test.support (GH-20765) Message-ID: https://github.com/python/cpython/commit/0d00b2a5d74390da7bbeff7dfa73abf2eb46124a commit: 0d00b2a5d74390da7bbeff7dfa73abf2eb46124a branch: master author: Hai Shi committer: GitHub date: 2020-06-10T14:29:02+02:00 summary: bpo-40275: Add os_helper submodule in test.support (GH-20765) files: A Lib/test/support/os_helper.py M Doc/library/test.rst M Lib/test/support/__init__.py diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 7580fb5e9b174..11d748466cba2 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -247,41 +247,6 @@ The :mod:`test.support` module defines the following constants: Path for shell if not on Windows; otherwise ``None``. -.. data:: FS_NONASCII - - A non-ASCII character encodable by :func:`os.fsencode`. - - -.. data:: TESTFN - - Set to a name that is safe to use as the name of a temporary file. Any - temporary file that is created should be closed and unlinked (removed). - - -.. data:: TESTFN_UNICODE - - Set to a non-ASCII name for a temporary file. - - -.. data:: TESTFN_UNENCODABLE - - Set to a filename (str type) that should not be able to be encoded by file - system encoding in strict mode. It may be ``None`` if it's not possible to - generate such a filename. - - -.. data:: TESTFN_UNDECODABLE - - Set to a filename (bytes type) that should not be able to be decoded by - file system encoding in strict mode. It may be ``None`` if it's not - possible to generate such a filename. - - -.. data:: TESTFN_NONASCII - - Set to a filename containing the :data:`FS_NONASCII` character. - - .. data:: LOOPBACK_TIMEOUT Timeout in seconds for tests using a network server listening on the network @@ -343,11 +308,6 @@ The :mod:`test.support` module defines the following constants: :data:`SHORT_TIMEOUT`. -.. data:: SAVEDCWD - - Set to :func:`os.getcwd`. - - .. data:: PGO Set when tests can be skipped when they are not useful for PGO. @@ -449,25 +409,6 @@ The :mod:`test.support` module defines the following functions: Delete *name* from ``sys.modules``. -.. function:: unlink(filename) - - Call :func:`os.unlink` on *filename*. On Windows platforms, this is - wrapped with a wait loop that checks for the existence fo the file. - - -.. function:: rmdir(filename) - - Call :func:`os.rmdir` on *filename*. On Windows platforms, this is - wrapped with a wait loop that checks for the existence of the file. - - -.. function:: rmtree(path) - - Call :func:`shutil.rmtree` on *path* or call :func:`os.lstat` and - :func:`os.rmdir` to remove a path and its contents. On Windows platforms, - this is wrapped with a wait loop that checks for the existence of the files. - - .. function:: make_legacy_pyc(source) Move a :pep:`3147`/:pep:`488` pyc file to its legacy pyc location and return the file @@ -521,16 +462,6 @@ The :mod:`test.support` module defines the following functions: rather than looking directly in the path directories. -.. function:: create_empty_file(filename) - - Create an empty file with *filename*. If it already exists, truncate it. - - -.. function:: fd_count() - - Count the number of open file descriptors. - - .. function:: match_test(test) Match *test* to patterns set in :func:`set_match_tests`. @@ -713,47 +644,6 @@ The :mod:`test.support` module defines the following functions: self.assertEqual(captured, "hello") -.. function:: temp_dir(path=None, quiet=False) - - A context manager that creates a temporary directory at *path* and - yields the directory. - - If *path* is ``None``, the temporary directory is created using - :func:`tempfile.mkdtemp`. If *quiet* is ``False``, the context manager - raises an exception on error. Otherwise, if *path* is specified and - cannot be created, only a warning is issued. - - -.. function:: change_cwd(path, quiet=False) - - A context manager that temporarily changes the current working - directory to *path* and yields the directory. - - If *quiet* is ``False``, the context manager raises an exception - on error. Otherwise, it issues only a warning and keeps the current - working directory the same. - - -.. function:: temp_cwd(name='tempcwd', quiet=False) - - A context manager that temporarily creates a new directory and - changes the current working directory (CWD). - - The context manager creates a temporary directory in the current - directory with name *name* before temporarily changing the current - working directory. If *name* is ``None``, the temporary directory is - created using :func:`tempfile.mkdtemp`. - - If *quiet* is ``False`` and it is not possible to create or change - the CWD, an error is raised. Otherwise, only a warning is raised - and the original CWD is used. - - -.. function:: temp_umask(umask) - - A context manager that temporarily sets the process umask. - - .. function:: disable_faulthandler() A context manager that replaces ``sys.stderr`` with ``sys.__stderr__``. @@ -851,28 +741,6 @@ The :mod:`test.support` module defines the following functions: header size equals *size*. -.. function:: can_symlink() - - Return ``True`` if the OS supports symbolic links, ``False`` - otherwise. - - -.. function:: can_xattr() - - Return ``True`` if the OS supports xattr, ``False`` - otherwise. - - -.. decorator:: skip_unless_symlink - - A decorator for running tests that require support for symbolic links. - - -.. decorator:: skip_unless_xattr - - A decorator for running tests that require support for xattr. - - .. decorator:: anticipate_failure(condition) A decorator to conditionally mark tests with @@ -992,12 +860,6 @@ The :mod:`test.support` module defines the following functions: wrap. -.. function:: make_bad_fd() - - Create an invalid file descriptor by opening and closing a temporary file, - and returning its descriptor. - - .. function:: check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None) Test for syntax errors in *statement* by attempting to compile *statement*. @@ -1144,11 +1006,6 @@ The :mod:`test.support` module defines the following functions: return load_package_tests(os.path.dirname(__file__), *args) -.. function:: fs_is_case_insensitive(directory) - - Return ``True`` if the file system for *directory* is case-insensitive. - - .. function:: detect_api_mismatch(ref_api, other_api, *, ignore=()) Returns the set of attributes, functions or methods of *ref_api* not @@ -1241,28 +1098,6 @@ The :mod:`test.support` module defines the following classes: attributes on the exception is :exc:`ResourceDenied` raised. -.. class:: EnvironmentVarGuard() - - Class used to temporarily set or unset environment variables. Instances can - be used as a context manager and have a complete dictionary interface for - querying/modifying the underlying ``os.environ``. After exit from the - context manager all changes to environment variables done through this - instance will be rolled back. - - .. versionchanged:: 3.1 - Added dictionary interface. - -.. method:: EnvironmentVarGuard.set(envvar, value) - - Temporarily set the environment variable ``envvar`` to the value of - ``value``. - - -.. method:: EnvironmentVarGuard.unset(envvar) - - Temporarily unset the environment variable ``envvar``. - - .. class:: SuppressCrashReport() A context manager used to try to prevent crash dialog popups on tests that @@ -1332,13 +1167,6 @@ The :mod:`test.support` module defines the following classes: Run *test* and return the result. -.. class:: FakePath(path) - - Simple :term:`path-like object`. It implements the :meth:`__fspath__` - method which just returns the *path* argument. If *path* is an exception, - it will be raised in :meth:`!__fspath__`. - - :mod:`test.support.socket_helper` --- Utilities for socket tests ================================================================ @@ -1634,3 +1462,187 @@ The :mod:`test.support.threading_helper` module provides support for threading t # (to avoid reference cycles) .. versionadded:: 3.8 + + +:mod:`test.support.os_helper` --- Utilities for os tests +======================================================================== + +.. module:: test.support.os_helper + :synopsis: Support for os tests. + +The :mod:`test.support.os_helper` module provides support for os tests. + +.. versionadded:: 3.10 + + +.. data:: FS_NONASCII + + A non-ASCII character encodable by :func:`os.fsencode`. + + +.. data:: SAVEDCWD + + Set to :func:`os.getcwd`. + + +.. data:: TESTFN + + Set to a name that is safe to use as the name of a temporary file. Any + temporary file that is created should be closed and unlinked (removed). + + +.. data:: TESTFN_NONASCII + + Set to a filename containing the :data:`FS_NONASCII` character. + + +.. data:: TESTFN_UNENCODABLE + + Set to a filename (str type) that should not be able to be encoded by file + system encoding in strict mode. It may be ``None`` if it's not possible to + generate such a filename. + + +.. data:: TESTFN_UNDECODABLE + + Set to a filename (bytes type) that should not be able to be decoded by + file system encoding in strict mode. It may be ``None`` if it's not + possible to generate such a filename. + + +.. data:: TESTFN_UNICODE + + Set to a non-ASCII name for a temporary file. + + +.. class:: EnvironmentVarGuard() + + Class used to temporarily set or unset environment variables. Instances can + be used as a context manager and have a complete dictionary interface for + querying/modifying the underlying ``os.environ``. After exit from the + context manager all changes to environment variables done through this + instance will be rolled back. + + .. versionchanged:: 3.1 + Added dictionary interface. + + +.. class:: FakePath(path) + + Simple :term:`path-like object`. It implements the :meth:`__fspath__` + method which just returns the *path* argument. If *path* is an exception, + it will be raised in :meth:`!__fspath__`. + + +.. method:: EnvironmentVarGuard.set(envvar, value) + + Temporarily set the environment variable ``envvar`` to the value of + ``value``. + + +.. method:: EnvironmentVarGuard.unset(envvar) + + Temporarily unset the environment variable ``envvar``. + + +.. function:: can_symlink() + + Return ``True`` if the OS supports symbolic links, ``False`` + otherwise. + + +.. function:: can_xattr() + + Return ``True`` if the OS supports xattr, ``False`` + otherwise. + + +.. function:: change_cwd(path, quiet=False) + + A context manager that temporarily changes the current working + directory to *path* and yields the directory. + + If *quiet* is ``False``, the context manager raises an exception + on error. Otherwise, it issues only a warning and keeps the current + working directory the same. + + +.. function:: create_empty_file(filename) + + Create an empty file with *filename*. If it already exists, truncate it. + + +.. function:: fd_count() + + Count the number of open file descriptors. + + +.. function:: fs_is_case_insensitive(directory) + + Return ``True`` if the file system for *directory* is case-insensitive. + + +.. function:: make_bad_fd() + + Create an invalid file descriptor by opening and closing a temporary file, + and returning its descriptor. + + +.. function:: rmdir(filename) + + Call :func:`os.rmdir` on *filename*. On Windows platforms, this is + wrapped with a wait loop that checks for the existence of the file. + + +.. function:: rmtree(path) + + Call :func:`shutil.rmtree` on *path* or call :func:`os.lstat` and + :func:`os.rmdir` to remove a path and its contents. On Windows platforms, + this is wrapped with a wait loop that checks for the existence of the files. + + +.. decorator:: skip_unless_symlink + + A decorator for running tests that require support for symbolic links. + + +.. decorator:: skip_unless_xattr + + A decorator for running tests that require support for xattr. + + +.. function:: temp_cwd(name='tempcwd', quiet=False) + + A context manager that temporarily creates a new directory and + changes the current working directory (CWD). + + The context manager creates a temporary directory in the current + directory with name *name* before temporarily changing the current + working directory. If *name* is ``None``, the temporary directory is + created using :func:`tempfile.mkdtemp`. + + If *quiet* is ``False`` and it is not possible to create or change + the CWD, an error is raised. Otherwise, only a warning is raised + and the original CWD is used. + + +.. function:: temp_dir(path=None, quiet=False) + + A context manager that creates a temporary directory at *path* and + yields the directory. + + If *path* is ``None``, the temporary directory is created using + :func:`tempfile.mkdtemp`. If *quiet* is ``False``, the context manager + raises an exception on error. Otherwise, if *path* is specified and + cannot be created, only a warning is issued. + + +.. function:: temp_umask(umask) + + A context manager that temporarily sets the process umask. + + +.. function:: unlink(filename) + + Call :func:`os.unlink` on *filename*. On Windows platforms, this is + wrapped with a wait loop that checks for the existence fo the file. diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index bb905bd895de8..3a5f7b556d767 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3,7 +3,6 @@ if __name__ != 'test.support': raise ImportError('support must be imported from the test package') -import collections.abc import contextlib import errno import fnmatch @@ -22,8 +21,19 @@ import unittest import warnings +from .os_helper import ( + FS_NONASCII, SAVEDCWD, TESTFN, TESTFN_NONASCII, + TESTFN_UNENCODABLE, TESTFN_UNDECODABLE, + TESTFN_UNICODE, can_symlink, can_xattr, + change_cwd, create_empty_file, fd_count, + fs_is_case_insensitive, make_bad_fd, rmdir, + rmtree, skip_unless_symlink, skip_unless_xattr, + temp_cwd, temp_dir, temp_umask, unlink, + EnvironmentVarGuard, FakePath, _longpath) + from .testresult import get_test_runner + __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", @@ -36,18 +46,15 @@ # io "record_original_stdout", "get_original_stdout", "captured_stdout", "captured_stdin", "captured_stderr", - # filesystem - "TESTFN", "SAVEDCWD", "unlink", "rmtree", "temp_cwd", "findfile", - "create_empty_file", "can_symlink", "fs_is_case_insensitive", # unittest "is_resource_enabled", "requires", "requires_freebsd_version", "requires_linux_version", "requires_mac_ver", "check_syntax_error", "check_syntax_warning", "TransientResource", "time_out", "socket_peer_reset", "ioerror_peer_reset", "BasicTestRunner", "run_unittest", "run_doctest", - "skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma", + "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", - "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", + "requires_IEEE_754", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", "ignore_warnings", @@ -57,13 +64,12 @@ # network "open_urlresource", # processes - 'temp_umask', "reap_children", + "reap_children", # miscellaneous "check_warnings", "check_no_resource_warning", "check_no_warnings", - "EnvironmentVarGuard", - "run_with_locale", "swap_item", + "run_with_locale", "swap_item", "findfile", "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", - "run_with_tz", "PGO", "missing_compiler_executable", "fd_count", + "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", ] @@ -318,6 +324,7 @@ def unload(name): except KeyError: pass + def _force_run(path, func, *args): try: return func(*args) @@ -328,124 +335,6 @@ def _force_run(path, func, *args): os.chmod(path, stat.S_IRWXU) return func(*args) -if sys.platform.startswith("win"): - def _waitfor(func, pathname, waitall=False): - # Perform the operation - func(pathname) - # Now setup the wait loop - if waitall: - dirname = pathname - else: - dirname, name = os.path.split(pathname) - dirname = dirname or '.' - # Check for `pathname` to be removed from the filesystem. - # The exponential backoff of the timeout amounts to a total - # of ~1 second after which the deletion is probably an error - # anyway. - # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is - # required when contention occurs. - timeout = 0.001 - while timeout < 1.0: - # Note we are only testing for the existence of the file(s) in - # the contents of the directory regardless of any security or - # access rights. If we have made it this far, we have sufficient - # permissions to do that much using Python's equivalent of the - # Windows API FindFirstFile. - # Other Windows APIs can fail or give incorrect results when - # dealing with files that are pending deletion. - L = os.listdir(dirname) - if not (L if waitall else name in L): - return - # Increase the timeout and try again - time.sleep(timeout) - timeout *= 2 - warnings.warn('tests may fail, delete still pending for ' + pathname, - RuntimeWarning, stacklevel=4) - - def _unlink(filename): - _waitfor(os.unlink, filename) - - def _rmdir(dirname): - _waitfor(os.rmdir, dirname) - - def _rmtree(path): - def _rmtree_inner(path): - for name in _force_run(path, os.listdir, path): - fullname = os.path.join(path, name) - try: - mode = os.lstat(fullname).st_mode - except OSError as exc: - print("support.rmtree(): os.lstat(%r) failed with %s" % (fullname, exc), - file=sys.__stderr__) - mode = 0 - if stat.S_ISDIR(mode): - _waitfor(_rmtree_inner, fullname, waitall=True) - _force_run(fullname, os.rmdir, fullname) - else: - _force_run(fullname, os.unlink, fullname) - _waitfor(_rmtree_inner, path, waitall=True) - _waitfor(lambda p: _force_run(p, os.rmdir, p), path) - - def _longpath(path): - try: - import ctypes - except ImportError: - # No ctypes means we can't expands paths. - pass - else: - buffer = ctypes.create_unicode_buffer(len(path) * 2) - length = ctypes.windll.kernel32.GetLongPathNameW(path, buffer, - len(buffer)) - if length: - return buffer[:length] - return path -else: - _unlink = os.unlink - _rmdir = os.rmdir - - def _rmtree(path): - import shutil - try: - shutil.rmtree(path) - return - except OSError: - pass - - def _rmtree_inner(path): - for name in _force_run(path, os.listdir, path): - fullname = os.path.join(path, name) - try: - mode = os.lstat(fullname).st_mode - except OSError: - mode = 0 - if stat.S_ISDIR(mode): - _rmtree_inner(fullname) - _force_run(path, os.rmdir, fullname) - else: - _force_run(path, os.unlink, fullname) - _rmtree_inner(path) - os.rmdir(path) - - def _longpath(path): - return path - -def unlink(filename): - try: - _unlink(filename) - except (FileNotFoundError, NotADirectoryError): - pass - -def rmdir(dirname): - try: - _rmdir(dirname) - except FileNotFoundError: - pass - -def rmtree(path): - try: - _rmtree(path) - except FileNotFoundError: - pass def make_legacy_pyc(source): """Move a PEP 3147/488 pyc file to its legacy pyc location. @@ -714,149 +603,10 @@ def requires_lzma(reason='requires lzma'): else: unix_shell = None -# Filename used for testing -if os.name == 'java': - # Jython disallows @ in module names - TESTFN = '$test' -else: - TESTFN = '@test' - -# Disambiguate TESTFN for parallel testing, while letting it remain a valid -# module name. -TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) - # Define the URL of a dedicated HTTP server for the network tests. # The URL must use clear-text HTTP: no redirection to encrypted HTTPS. TEST_HTTP_URL = "http://www.pythontest.net" -# FS_NONASCII: non-ASCII character encodable by os.fsencode(), -# or None if there is no such character. -FS_NONASCII = None -for character in ( - # First try printable and common characters to have a readable filename. - # For each character, the encoding list are just example of encodings able - # to encode the character (the list is not exhaustive). - - # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 - '\u00E6', - # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 - '\u0130', - # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 - '\u0141', - # U+03C6 (Greek Small Letter Phi): cp1253 - '\u03C6', - # U+041A (Cyrillic Capital Letter Ka): cp1251 - '\u041A', - # U+05D0 (Hebrew Letter Alef): Encodable to cp424 - '\u05D0', - # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic - '\u060C', - # U+062A (Arabic Letter Teh): cp720 - '\u062A', - # U+0E01 (Thai Character Ko Kai): cp874 - '\u0E01', - - # Then try more "special" characters. "special" because they may be - # interpreted or displayed differently depending on the exact locale - # encoding and the font. - - # U+00A0 (No-Break Space) - '\u00A0', - # U+20AC (Euro Sign) - '\u20AC', -): - try: - # If Python is set up to use the legacy 'mbcs' in Windows, - # 'replace' error mode is used, and encode() returns b'?' - # for characters missing in the ANSI codepage - if os.fsdecode(os.fsencode(character)) != character: - raise UnicodeError - except UnicodeError: - pass - else: - FS_NONASCII = character - break - -# TESTFN_UNICODE is a non-ascii filename -TESTFN_UNICODE = TESTFN + "-\xe0\xf2\u0258\u0141\u011f" -if sys.platform == 'darwin': - # In Mac OS X's VFS API file names are, by definition, canonically - # decomposed Unicode, encoded using UTF-8. See QA1173: - # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html - import unicodedata - TESTFN_UNICODE = unicodedata.normalize('NFD', TESTFN_UNICODE) - -# TESTFN_UNENCODABLE is a filename (str type) that should *not* be able to be -# encoded by the filesystem encoding (in strict mode). It can be None if we -# cannot generate such filename. -TESTFN_UNENCODABLE = None -if os.name == 'nt': - # skip win32s (0) or Windows 9x/ME (1) - if sys.getwindowsversion().platform >= 2: - # Different kinds of characters from various languages to minimize the - # probability that the whole name is encodable to MBCS (issue #9819) - TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80" - try: - TESTFN_UNENCODABLE.encode(sys.getfilesystemencoding()) - except UnicodeEncodeError: - pass - else: - print('WARNING: The filename %r CAN be encoded by the filesystem encoding (%s). ' - 'Unicode filename tests may not be effective' - % (TESTFN_UNENCODABLE, sys.getfilesystemencoding())) - TESTFN_UNENCODABLE = None -# Mac OS X denies unencodable filenames (invalid utf-8) -elif sys.platform != 'darwin': - try: - # ascii and utf-8 cannot encode the byte 0xff - b'\xff'.decode(sys.getfilesystemencoding()) - except UnicodeDecodeError: - # 0xff will be encoded using the surrogate character u+DCFF - TESTFN_UNENCODABLE = TESTFN \ - + b'-\xff'.decode(sys.getfilesystemencoding(), 'surrogateescape') - else: - # File system encoding (eg. ISO-8859-* encodings) can encode - # the byte 0xff. Skip some unicode filename tests. - pass - -# TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be -# decoded from the filesystem encoding (in strict mode). It can be None if we -# cannot generate such filename (ex: the latin1 encoding can decode any byte -# sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks -# to the surrogateescape error handler (PEP 383), but not from the filesystem -# encoding in strict mode. -TESTFN_UNDECODABLE = None -for name in ( - # b'\xff' is not decodable by os.fsdecode() with code page 932. Windows - # accepts it to create a file or a directory, or don't accept to enter to - # such directory (when the bytes name is used). So test b'\xe7' first: it is - # not decodable from cp932. - b'\xe7w\xf0', - # undecodable from ASCII, UTF-8 - b'\xff', - # undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856 - # and cp857 - b'\xae\xd5' - # undecodable from UTF-8 (UNIX and Mac OS X) - b'\xed\xb2\x80', b'\xed\xb4\x80', - # undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252, - # cp1253, cp1254, cp1255, cp1257, cp1258 - b'\x81\x98', -): - try: - name.decode(sys.getfilesystemencoding()) - except UnicodeDecodeError: - TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name - break - -if FS_NONASCII: - TESTFN_NONASCII = TESTFN + '-' + FS_NONASCII -else: - TESTFN_NONASCII = None - -# Save the initial cwd -SAVEDCWD = os.getcwd() - # Set by libregrtest/main.py so we can skip tests that are not # useful for PGO PGO = False @@ -865,103 +615,6 @@ def requires_lzma(reason='requires lzma'): # PGO task. If this is True, PGO is also True. PGO_EXTENDED = False - at contextlib.contextmanager -def temp_dir(path=None, quiet=False): - """Return a context manager that creates a temporary directory. - - Arguments: - - path: the directory to create temporarily. If omitted or None, - defaults to creating a temporary directory using tempfile.mkdtemp. - - quiet: if False (the default), the context manager raises an exception - on error. Otherwise, if the path is specified and cannot be - created, only a warning is issued. - - """ - import tempfile - dir_created = False - if path is None: - path = tempfile.mkdtemp() - dir_created = True - path = os.path.realpath(path) - else: - try: - os.mkdir(path) - dir_created = True - except OSError as exc: - if not quiet: - raise - warnings.warn(f'tests may fail, unable to create ' - f'temporary directory {path!r}: {exc}', - RuntimeWarning, stacklevel=3) - if dir_created: - pid = os.getpid() - try: - yield path - finally: - # In case the process forks, let only the parent remove the - # directory. The child has a different process id. (bpo-30028) - if dir_created and pid == os.getpid(): - rmtree(path) - - at contextlib.contextmanager -def change_cwd(path, quiet=False): - """Return a context manager that changes the current working directory. - - Arguments: - - path: the directory to use as the temporary current working directory. - - quiet: if False (the default), the context manager raises an exception - on error. Otherwise, it issues only a warning and keeps the current - working directory the same. - - """ - saved_dir = os.getcwd() - try: - os.chdir(os.path.realpath(path)) - except OSError as exc: - if not quiet: - raise - warnings.warn(f'tests may fail, unable to change the current working ' - f'directory to {path!r}: {exc}', - RuntimeWarning, stacklevel=3) - try: - yield os.getcwd() - finally: - os.chdir(saved_dir) - - - at contextlib.contextmanager -def temp_cwd(name='tempcwd', quiet=False): - """ - Context manager that temporarily creates and changes the CWD. - - The function temporarily changes the current working directory - after creating a temporary directory in the current directory with - name *name*. If *name* is None, the temporary directory is - created using tempfile.mkdtemp. - - If *quiet* is False (default) and it is not possible to - create or change the CWD, an error is raised. If *quiet* is True, - only a warning is raised and the original CWD is used. - - """ - with temp_dir(path=name, quiet=quiet) as temp_path: - with change_cwd(temp_path, quiet=quiet) as cwd_dir: - yield cwd_dir - -if hasattr(os, "umask"): - @contextlib.contextmanager - def temp_umask(umask): - """Context manager that temporarily sets the process umask.""" - oldmask = os.umask(umask) - try: - yield - finally: - os.umask(oldmask) - # TEST_HOME_DIR refers to the top level directory of the "test" package # that contains Python's regression test suite TEST_SUPPORT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -970,6 +623,7 @@ def temp_umask(umask): # TEST_DATA_DIR is used as a target download location for remote resources TEST_DATA_DIR = os.path.join(TEST_HOME_DIR, "data") + def findfile(filename, subdir=None): """Try to find a file on sys.path or in the test directory. If it is not found the argument passed to the function is returned (this does not @@ -988,10 +642,6 @@ def findfile(filename, subdir=None): if os.path.exists(fn): return fn return filename -def create_empty_file(filename): - """Create an empty file. If the file already exists, truncate it.""" - fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC) - os.close(fd) def sortdict(dict): "Like repr(dict), but in sorted order." @@ -1000,19 +650,6 @@ def sortdict(dict): withcommas = ", ".join(reprpairs) return "{%s}" % withcommas -def make_bad_fd(): - """ - Create an invalid file descriptor by opening and closing a file and return - its fd. - """ - file = open(TESTFN, "wb") - try: - return file.fileno() - finally: - file.close() - unlink(TESTFN) - - def check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None): with testcase.assertRaisesRegex(SyntaxError, errtext) as cm: compile(statement, '', 'exec') @@ -1265,59 +902,6 @@ def __exit__(self, *ignore_exc): sys.modules.update(self.original_modules) -class EnvironmentVarGuard(collections.abc.MutableMapping): - - """Class to help protect the environment variable properly. Can be used as - a context manager.""" - - def __init__(self): - self._environ = os.environ - self._changed = {} - - def __getitem__(self, envvar): - return self._environ[envvar] - - def __setitem__(self, envvar, value): - # Remember the initial value on the first access - if envvar not in self._changed: - self._changed[envvar] = self._environ.get(envvar) - self._environ[envvar] = value - - def __delitem__(self, envvar): - # Remember the initial value on the first access - if envvar not in self._changed: - self._changed[envvar] = self._environ.get(envvar) - if envvar in self._environ: - del self._environ[envvar] - - def keys(self): - return self._environ.keys() - - def __iter__(self): - return iter(self._environ) - - def __len__(self): - return len(self._environ) - - def set(self, envvar, value): - self[envvar] = value - - def unset(self, envvar): - del self[envvar] - - def __enter__(self): - return self - - def __exit__(self, *ignore_exc): - for (k, v) in self._changed.items(): - if v is None: - if k in self._environ: - del self._environ[k] - else: - self._environ[k] = v - os.environ = self._environ - - class DirsOnSysPath(object): """Context manager to temporarily add directories to sys.path. @@ -2133,28 +1717,6 @@ def match_value(self, k, dv, v): return result -_can_symlink = None -def can_symlink(): - global _can_symlink - if _can_symlink is not None: - return _can_symlink - symlink_path = TESTFN + "can_symlink" - try: - os.symlink(TESTFN, symlink_path) - can = True - except (OSError, NotImplementedError, AttributeError): - can = False - else: - os.remove(symlink_path) - _can_symlink = can - return can - -def skip_unless_symlink(test): - """Skip decorator for tests that require functional symlink""" - ok = can_symlink() - msg = "Requires functional symlink implementation" - return test if ok else unittest.skip(msg)(test) - _buggy_ucrt = None def skip_if_buggy_ucrt_strfptime(test): """ @@ -2256,45 +1818,6 @@ def call_link(self, *args, returncode=0): return self._call(self.link, args, self._env, returncode) -_can_xattr = None -def can_xattr(): - import tempfile - global _can_xattr - if _can_xattr is not None: - return _can_xattr - if not hasattr(os, "setxattr"): - can = False - else: - import platform - tmp_dir = tempfile.mkdtemp() - tmp_fp, tmp_name = tempfile.mkstemp(dir=tmp_dir) - try: - with open(TESTFN, "wb") as fp: - try: - # TESTFN & tempfile may use different file systems with - # different capabilities - os.setxattr(tmp_fp, b"user.test", b"") - os.setxattr(tmp_name, b"trusted.foo", b"42") - os.setxattr(fp.fileno(), b"user.test", b"") - # Kernels < 2.6.39 don't respect setxattr flags. - kernel_version = platform.release() - m = re.match(r"2.6.(\d{1,2})", kernel_version) - can = m is None or int(m.group(1)) >= 39 - except OSError: - can = False - finally: - unlink(TESTFN) - unlink(tmp_name) - rmdir(tmp_dir) - _can_xattr = can - return can - -def skip_unless_xattr(test): - """Skip decorator for tests that require functional extended attributes""" - ok = can_xattr() - msg = "no non-broken extended attribute support" - return test if ok else unittest.skip(msg)(test) - def skip_if_pgo_task(test): """Skip decorator for tests not run in (non-extended) PGO task""" ok = not PGO or PGO_EXTENDED @@ -2302,20 +1825,6 @@ def skip_if_pgo_task(test): return test if ok else unittest.skip(msg)(test) -def fs_is_case_insensitive(directory): - """Detects if the file system for the specified directory is case-insensitive.""" - import tempfile - with tempfile.NamedTemporaryFile(dir=directory) as base: - base_path = base.name - case_path = base_path.upper() - if case_path == base_path: - case_path = base_path.lower() - try: - return os.path.samefile(base_path, case_path) - except FileNotFoundError: - return False - - def detect_api_mismatch(ref_api, other_api, *, ignore=()): """Returns the set of items in ref_api not in other_api, except for a defined list of items to be ignored in this check. @@ -2623,65 +2132,6 @@ def disable_faulthandler(): faulthandler.enable(file=fd, all_threads=True) -def fd_count(): - """Count the number of open file descriptors. - """ - if sys.platform.startswith(('linux', 'freebsd')): - try: - names = os.listdir("/proc/self/fd") - # Subtract one because listdir() internally opens a file - # descriptor to list the content of the /proc/self/fd/ directory. - return len(names) - 1 - except FileNotFoundError: - pass - - MAXFD = 256 - if hasattr(os, 'sysconf'): - try: - MAXFD = os.sysconf("SC_OPEN_MAX") - except OSError: - pass - - old_modes = None - if sys.platform == 'win32': - # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process - # on invalid file descriptor if Python is compiled in debug mode - try: - import msvcrt - msvcrt.CrtSetReportMode - except (AttributeError, ImportError): - # no msvcrt or a release build - pass - else: - old_modes = {} - for report_type in (msvcrt.CRT_WARN, - msvcrt.CRT_ERROR, - msvcrt.CRT_ASSERT): - old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0) - - try: - count = 0 - for fd in range(MAXFD): - try: - # Prefer dup() over fstat(). fstat() can require input/output - # whereas dup() doesn't. - fd2 = os.dup(fd) - except OSError as e: - if e.errno != errno.EBADF: - raise - else: - os.close(fd2) - count += 1 - finally: - if old_modes is not None: - for report_type in (msvcrt.CRT_WARN, - msvcrt.CRT_ERROR, - msvcrt.CRT_ASSERT): - msvcrt.CrtSetReportMode(report_type, old_modes[report_type]) - - return count - - class SaveSignals: """ Save and restore signal handlers. @@ -2726,24 +2176,6 @@ def with_pymalloc(): return _testcapi.WITH_PYMALLOC -class FakePath: - """Simple implementing of the path protocol. - """ - def __init__(self, path): - self.path = path - - def __repr__(self): - return f'' - - def __fspath__(self): - if (isinstance(self.path, BaseException) or - isinstance(self.path, type) and - issubclass(self.path, BaseException)): - raise self.path - else: - return self.path - - class _ALWAYS_EQ: """ Object that is equal to anything. diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py new file mode 100644 index 0000000000000..d3347027cf204 --- /dev/null +++ b/Lib/test/support/os_helper.py @@ -0,0 +1,611 @@ +import collections.abc +import contextlib +import errno +import os +import re +import stat +import sys +import time +import unittest +import warnings + + +# Filename used for testing +if os.name == 'java': + # Jython disallows @ in module names + TESTFN = '$test' +else: + TESTFN = '@test' + +# Disambiguate TESTFN for parallel testing, while letting it remain a valid +# module name. +TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) + +# TESTFN_UNICODE is a non-ascii filename +TESTFN_UNICODE = TESTFN + "-\xe0\xf2\u0258\u0141\u011f" +if sys.platform == 'darwin': + # In Mac OS X's VFS API file names are, by definition, canonically + # decomposed Unicode, encoded using UTF-8. See QA1173: + # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html + import unicodedata + TESTFN_UNICODE = unicodedata.normalize('NFD', TESTFN_UNICODE) + +# TESTFN_UNENCODABLE is a filename (str type) that should *not* be able to be +# encoded by the filesystem encoding (in strict mode). It can be None if we +# cannot generate such filename. +TESTFN_UNENCODABLE = None +if os.name == 'nt': + # skip win32s (0) or Windows 9x/ME (1) + if sys.getwindowsversion().platform >= 2: + # Different kinds of characters from various languages to minimize the + # probability that the whole name is encodable to MBCS (issue #9819) + TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80" + try: + TESTFN_UNENCODABLE.encode(sys.getfilesystemencoding()) + except UnicodeEncodeError: + pass + else: + print('WARNING: The filename %r CAN be encoded by the filesystem ' + 'encoding (%s). Unicode filename tests may not be effective' + % (TESTFN_UNENCODABLE, sys.getfilesystemencoding())) + TESTFN_UNENCODABLE = None +# Mac OS X denies unencodable filenames (invalid utf-8) +elif sys.platform != 'darwin': + try: + # ascii and utf-8 cannot encode the byte 0xff + b'\xff'.decode(sys.getfilesystemencoding()) + except UnicodeDecodeError: + # 0xff will be encoded using the surrogate character u+DCFF + TESTFN_UNENCODABLE = TESTFN \ + + b'-\xff'.decode(sys.getfilesystemencoding(), 'surrogateescape') + else: + # File system encoding (eg. ISO-8859-* encodings) can encode + # the byte 0xff. Skip some unicode filename tests. + pass + +# FS_NONASCII: non-ASCII character encodable by os.fsencode(), +# or None if there is no such character. +FS_NONASCII = None +for character in ( + # First try printable and common characters to have a readable filename. + # For each character, the encoding list are just example of encodings able + # to encode the character (the list is not exhaustive). + + # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 + '\u00E6', + # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 + '\u0130', + # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 + '\u0141', + # U+03C6 (Greek Small Letter Phi): cp1253 + '\u03C6', + # U+041A (Cyrillic Capital Letter Ka): cp1251 + '\u041A', + # U+05D0 (Hebrew Letter Alef): Encodable to cp424 + '\u05D0', + # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic + '\u060C', + # U+062A (Arabic Letter Teh): cp720 + '\u062A', + # U+0E01 (Thai Character Ko Kai): cp874 + '\u0E01', + + # Then try more "special" characters. "special" because they may be + # interpreted or displayed differently depending on the exact locale + # encoding and the font. + + # U+00A0 (No-Break Space) + '\u00A0', + # U+20AC (Euro Sign) + '\u20AC', +): + try: + # If Python is set up to use the legacy 'mbcs' in Windows, + # 'replace' error mode is used, and encode() returns b'?' + # for characters missing in the ANSI codepage + if os.fsdecode(os.fsencode(character)) != character: + raise UnicodeError + except UnicodeError: + pass + else: + FS_NONASCII = character + break + +# Save the initial cwd +SAVEDCWD = os.getcwd() + +# TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be +# decoded from the filesystem encoding (in strict mode). It can be None if we +# cannot generate such filename (ex: the latin1 encoding can decode any byte +# sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks +# to the surrogateescape error handler (PEP 383), but not from the filesystem +# encoding in strict mode. +TESTFN_UNDECODABLE = None +for name in ( + # b'\xff' is not decodable by os.fsdecode() with code page 932. Windows + # accepts it to create a file or a directory, or don't accept to enter to + # such directory (when the bytes name is used). So test b'\xe7' first: + # it is not decodable from cp932. + b'\xe7w\xf0', + # undecodable from ASCII, UTF-8 + b'\xff', + # undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856 + # and cp857 + b'\xae\xd5' + # undecodable from UTF-8 (UNIX and Mac OS X) + b'\xed\xb2\x80', b'\xed\xb4\x80', + # undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252, + # cp1253, cp1254, cp1255, cp1257, cp1258 + b'\x81\x98', +): + try: + name.decode(sys.getfilesystemencoding()) + except UnicodeDecodeError: + TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name + break + +if FS_NONASCII: + TESTFN_NONASCII = TESTFN + '-' + FS_NONASCII +else: + TESTFN_NONASCII = None + + +def make_bad_fd(): + """ + Create an invalid file descriptor by opening and closing a file and return + its fd. + """ + file = open(TESTFN, "wb") + try: + return file.fileno() + finally: + file.close() + unlink(TESTFN) + + +_can_symlink = None + + +def can_symlink(): + global _can_symlink + if _can_symlink is not None: + return _can_symlink + symlink_path = TESTFN + "can_symlink" + try: + os.symlink(TESTFN, symlink_path) + can = True + except (OSError, NotImplementedError, AttributeError): + can = False + else: + os.remove(symlink_path) + _can_symlink = can + return can + + +def skip_unless_symlink(test): + """Skip decorator for tests that require functional symlink""" + ok = can_symlink() + msg = "Requires functional symlink implementation" + return test if ok else unittest.skip(msg)(test) + + +_can_xattr = None + + +def can_xattr(): + import tempfile + global _can_xattr + if _can_xattr is not None: + return _can_xattr + if not hasattr(os, "setxattr"): + can = False + else: + import platform + tmp_dir = tempfile.mkdtemp() + tmp_fp, tmp_name = tempfile.mkstemp(dir=tmp_dir) + try: + with open(TESTFN, "wb") as fp: + try: + # TESTFN & tempfile may use different file systems with + # different capabilities + os.setxattr(tmp_fp, b"user.test", b"") + os.setxattr(tmp_name, b"trusted.foo", b"42") + os.setxattr(fp.fileno(), b"user.test", b"") + # Kernels < 2.6.39 don't respect setxattr flags. + kernel_version = platform.release() + m = re.match(r"2.6.(\d{1,2})", kernel_version) + can = m is None or int(m.group(1)) >= 39 + except OSError: + can = False + finally: + unlink(TESTFN) + unlink(tmp_name) + rmdir(tmp_dir) + _can_xattr = can + return can + + +def skip_unless_xattr(test): + """Skip decorator for tests that require functional extended attributes""" + ok = can_xattr() + msg = "no non-broken extended attribute support" + return test if ok else unittest.skip(msg)(test) + + +def unlink(filename): + try: + _unlink(filename) + except (FileNotFoundError, NotADirectoryError): + pass + + +if sys.platform.startswith("win"): + def _waitfor(func, pathname, waitall=False): + # Perform the operation + func(pathname) + # Now setup the wait loop + if waitall: + dirname = pathname + else: + dirname, name = os.path.split(pathname) + dirname = dirname or '.' + # Check for `pathname` to be removed from the filesystem. + # The exponential backoff of the timeout amounts to a total + # of ~1 second after which the deletion is probably an error + # anyway. + # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is + # required when contention occurs. + timeout = 0.001 + while timeout < 1.0: + # Note we are only testing for the existence of the file(s) in + # the contents of the directory regardless of any security or + # access rights. If we have made it this far, we have sufficient + # permissions to do that much using Python's equivalent of the + # Windows API FindFirstFile. + # Other Windows APIs can fail or give incorrect results when + # dealing with files that are pending deletion. + L = os.listdir(dirname) + if not (L if waitall else name in L): + return + # Increase the timeout and try again + time.sleep(timeout) + timeout *= 2 + warnings.warn('tests may fail, delete still pending for ' + pathname, + RuntimeWarning, stacklevel=4) + + def _unlink(filename): + _waitfor(os.unlink, filename) + + def _rmdir(dirname): + _waitfor(os.rmdir, dirname) + + def _rmtree(path): + from test.support import _force_run + + def _rmtree_inner(path): + for name in _force_run(path, os.listdir, path): + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except OSError as exc: + print("support.rmtree(): os.lstat(%r) failed with %s" + % (fullname, exc), + file=sys.__stderr__) + mode = 0 + if stat.S_ISDIR(mode): + _waitfor(_rmtree_inner, fullname, waitall=True) + _force_run(fullname, os.rmdir, fullname) + else: + _force_run(fullname, os.unlink, fullname) + _waitfor(_rmtree_inner, path, waitall=True) + _waitfor(lambda p: _force_run(p, os.rmdir, p), path) + + def _longpath(path): + try: + import ctypes + except ImportError: + # No ctypes means we can't expands paths. + pass + else: + buffer = ctypes.create_unicode_buffer(len(path) * 2) + length = ctypes.windll.kernel32.GetLongPathNameW(path, buffer, + len(buffer)) + if length: + return buffer[:length] + return path +else: + _unlink = os.unlink + _rmdir = os.rmdir + + def _rmtree(path): + import shutil + try: + shutil.rmtree(path) + return + except OSError: + pass + + def _rmtree_inner(path): + from test.support import _force_run + for name in _force_run(path, os.listdir, path): + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except OSError: + mode = 0 + if stat.S_ISDIR(mode): + _rmtree_inner(fullname) + _force_run(path, os.rmdir, fullname) + else: + _force_run(path, os.unlink, fullname) + _rmtree_inner(path) + os.rmdir(path) + + def _longpath(path): + return path + + +def rmdir(dirname): + try: + _rmdir(dirname) + except FileNotFoundError: + pass + + +def rmtree(path): + try: + _rmtree(path) + except FileNotFoundError: + pass + + + at contextlib.contextmanager +def temp_dir(path=None, quiet=False): + """Return a context manager that creates a temporary directory. + + Arguments: + + path: the directory to create temporarily. If omitted or None, + defaults to creating a temporary directory using tempfile.mkdtemp. + + quiet: if False (the default), the context manager raises an exception + on error. Otherwise, if the path is specified and cannot be + created, only a warning is issued. + + """ + import tempfile + dir_created = False + if path is None: + path = tempfile.mkdtemp() + dir_created = True + path = os.path.realpath(path) + else: + try: + os.mkdir(path) + dir_created = True + except OSError as exc: + if not quiet: + raise + warnings.warn(f'tests may fail, unable to create ' + f'temporary directory {path!r}: {exc}', + RuntimeWarning, stacklevel=3) + if dir_created: + pid = os.getpid() + try: + yield path + finally: + # In case the process forks, let only the parent remove the + # directory. The child has a different process id. (bpo-30028) + if dir_created and pid == os.getpid(): + rmtree(path) + + + at contextlib.contextmanager +def change_cwd(path, quiet=False): + """Return a context manager that changes the current working directory. + + Arguments: + + path: the directory to use as the temporary current working directory. + + quiet: if False (the default), the context manager raises an exception + on error. Otherwise, it issues only a warning and keeps the current + working directory the same. + + """ + saved_dir = os.getcwd() + try: + os.chdir(os.path.realpath(path)) + except OSError as exc: + if not quiet: + raise + warnings.warn(f'tests may fail, unable to change the current working ' + f'directory to {path!r}: {exc}', + RuntimeWarning, stacklevel=3) + try: + yield os.getcwd() + finally: + os.chdir(saved_dir) + + + at contextlib.contextmanager +def temp_cwd(name='tempcwd', quiet=False): + """ + Context manager that temporarily creates and changes the CWD. + + The function temporarily changes the current working directory + after creating a temporary directory in the current directory with + name *name*. If *name* is None, the temporary directory is + created using tempfile.mkdtemp. + + If *quiet* is False (default) and it is not possible to + create or change the CWD, an error is raised. If *quiet* is True, + only a warning is raised and the original CWD is used. + + """ + with temp_dir(path=name, quiet=quiet) as temp_path: + with change_cwd(temp_path, quiet=quiet) as cwd_dir: + yield cwd_dir + + +def create_empty_file(filename): + """Create an empty file. If the file already exists, truncate it.""" + fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC) + os.close(fd) + + +def fs_is_case_insensitive(directory): + """Detects if the file system for the specified directory + is case-insensitive.""" + import tempfile + with tempfile.NamedTemporaryFile(dir=directory) as base: + base_path = base.name + case_path = base_path.upper() + if case_path == base_path: + case_path = base_path.lower() + try: + return os.path.samefile(base_path, case_path) + except FileNotFoundError: + return False + + +class FakePath: + """Simple implementing of the path protocol. + """ + def __init__(self, path): + self.path = path + + def __repr__(self): + return f'' + + def __fspath__(self): + if (isinstance(self.path, BaseException) or + isinstance(self.path, type) and + issubclass(self.path, BaseException)): + raise self.path + else: + return self.path + + +def fd_count(): + """Count the number of open file descriptors. + """ + if sys.platform.startswith(('linux', 'freebsd')): + try: + names = os.listdir("/proc/self/fd") + # Subtract one because listdir() internally opens a file + # descriptor to list the content of the /proc/self/fd/ directory. + return len(names) - 1 + except FileNotFoundError: + pass + + MAXFD = 256 + if hasattr(os, 'sysconf'): + try: + MAXFD = os.sysconf("SC_OPEN_MAX") + except OSError: + pass + + old_modes = None + if sys.platform == 'win32': + # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process + # on invalid file descriptor if Python is compiled in debug mode + try: + import msvcrt + msvcrt.CrtSetReportMode + except (AttributeError, ImportError): + # no msvcrt or a release build + pass + else: + old_modes = {} + for report_type in (msvcrt.CRT_WARN, + msvcrt.CRT_ERROR, + msvcrt.CRT_ASSERT): + old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, + 0) + + try: + count = 0 + for fd in range(MAXFD): + try: + # Prefer dup() over fstat(). fstat() can require input/output + # whereas dup() doesn't. + fd2 = os.dup(fd) + except OSError as e: + if e.errno != errno.EBADF: + raise + else: + os.close(fd2) + count += 1 + finally: + if old_modes is not None: + for report_type in (msvcrt.CRT_WARN, + msvcrt.CRT_ERROR, + msvcrt.CRT_ASSERT): + msvcrt.CrtSetReportMode(report_type, old_modes[report_type]) + + return count + + +if hasattr(os, "umask"): + @contextlib.contextmanager + def temp_umask(umask): + """Context manager that temporarily sets the process umask.""" + oldmask = os.umask(umask) + try: + yield + finally: + os.umask(oldmask) + + +class EnvironmentVarGuard(collections.abc.MutableMapping): + + """Class to help protect the environment variable properly. Can be used as + a context manager.""" + + def __init__(self): + self._environ = os.environ + self._changed = {} + + def __getitem__(self, envvar): + return self._environ[envvar] + + def __setitem__(self, envvar, value): + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = self._environ.get(envvar) + self._environ[envvar] = value + + def __delitem__(self, envvar): + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = self._environ.get(envvar) + if envvar in self._environ: + del self._environ[envvar] + + def keys(self): + return self._environ.keys() + + def __iter__(self): + return iter(self._environ) + + def __len__(self): + return len(self._environ) + + def set(self, envvar, value): + self[envvar] = value + + def unset(self, envvar): + del self[envvar] + + def __enter__(self): + return self + + def __exit__(self, *ignore_exc): + for (k, v) in self._changed.items(): + if v is None: + if k in self._environ: + del self._environ[k] + else: + self._environ[k] = v + os.environ = self._environ From webhook-mailer at python.org Wed Jun 10 09:07:11 2020 From: webhook-mailer at python.org (Pablo Galindo) Date: Wed, 10 Jun 2020 13:07:11 -0000 Subject: [Python-checkins] Raise specialised syntax error for invalid lambda parameters (GH-20776) Message-ID: https://github.com/python/cpython/commit/c6483c989694cfa328dabd45eb191440da54bc68 commit: c6483c989694cfa328dabd45eb191440da54bc68 branch: master author: Pablo Galindo committer: GitHub date: 2020-06-10T14:07:06+01:00 summary: Raise specialised syntax error for invalid lambda parameters (GH-20776) files: M Grammar/python.gram M Lib/test/test_positional_only_arg.py M Parser/pegen/parse.c diff --git a/Grammar/python.gram b/Grammar/python.gram index dd425eff30b7d..2c350ef68a214 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -329,7 +329,11 @@ expression[expr_ty] (memo): | lambdef lambdef[expr_ty]: - | 'lambda' a=[lambda_parameters] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) } + | 'lambda' a=[lambda_params] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) } + +lambda_params[arguments_ty]: + | invalid_lambda_parameters + | lambda_parameters # lambda_parameters etc. duplicates parameters but without annotations # or type comments, and if there's no comma after a parameter, we expect @@ -669,6 +673,9 @@ invalid_dict_comprehension: invalid_parameters: | param_no_default* (slash_with_default | param_with_default+) param_no_default { RAISE_SYNTAX_ERROR("non-default argument follows default argument") } +invalid_lambda_parameters: + | lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default { + RAISE_SYNTAX_ERROR("non-default argument follows default argument") } invalid_star_etc: | '*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") } | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") } diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index f7bd401804364..0a9503e2025d6 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -4,7 +4,7 @@ import pickle import unittest -from test.support import check_syntax_error, use_old_parser +from test.support import check_syntax_error def global_pos_only_f(a, b, /): @@ -23,12 +23,10 @@ def assertRaisesSyntaxError(self, codestr, regex="invalid syntax"): compile(codestr + "\n", "", "single") def test_invalid_syntax_errors(self): - if use_old_parser(): - check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument") - + check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument") check_syntax_error(self, "def f(*args, /): pass") check_syntax_error(self, "def f(*args, a, /): pass") check_syntax_error(self, "def f(**kwargs, /): pass") @@ -46,12 +44,10 @@ def test_invalid_syntax_errors(self): check_syntax_error(self, "def f(a, *, c, /, d, e): pass") def test_invalid_syntax_errors_async(self): - if use_old_parser(): - check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument") - + check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument") check_syntax_error(self, "async def f(*args, /): pass") check_syntax_error(self, "async def f(*args, a, /): pass") check_syntax_error(self, "async def f(**kwargs, /): pass") @@ -235,11 +231,9 @@ def test_lambdas(self): self.assertEqual(x(1, 2), 3) def test_invalid_syntax_lambda(self): - if use_old_parser(): - check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument") - + check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument") check_syntax_error(self, "lambda *args, /: None") check_syntax_error(self, "lambda *args, a, /: None") check_syntax_error(self, "lambda **kwargs, /: None") diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c index e5738e3e04afe..4f13bf772f261 100644 --- a/Parser/pegen/parse.c +++ b/Parser/pegen/parse.c @@ -144,244 +144,249 @@ static KeywordToken *reserved_keywords[] = { #define expressions_type 1066 #define expression_type 1067 #define lambdef_type 1068 -#define lambda_parameters_type 1069 -#define lambda_slash_no_default_type 1070 -#define lambda_slash_with_default_type 1071 -#define lambda_star_etc_type 1072 -#define lambda_kwds_type 1073 -#define lambda_param_no_default_type 1074 -#define lambda_param_with_default_type 1075 -#define lambda_param_maybe_default_type 1076 -#define lambda_param_type 1077 -#define disjunction_type 1078 -#define conjunction_type 1079 -#define inversion_type 1080 -#define comparison_type 1081 -#define compare_op_bitwise_or_pair_type 1082 -#define eq_bitwise_or_type 1083 -#define noteq_bitwise_or_type 1084 -#define lte_bitwise_or_type 1085 -#define lt_bitwise_or_type 1086 -#define gte_bitwise_or_type 1087 -#define gt_bitwise_or_type 1088 -#define notin_bitwise_or_type 1089 -#define in_bitwise_or_type 1090 -#define isnot_bitwise_or_type 1091 -#define is_bitwise_or_type 1092 -#define bitwise_or_type 1093 // Left-recursive -#define bitwise_xor_type 1094 // Left-recursive -#define bitwise_and_type 1095 // Left-recursive -#define shift_expr_type 1096 // Left-recursive -#define sum_type 1097 // Left-recursive -#define term_type 1098 // Left-recursive -#define factor_type 1099 -#define power_type 1100 -#define await_primary_type 1101 -#define primary_type 1102 // Left-recursive -#define slices_type 1103 -#define slice_type 1104 -#define atom_type 1105 -#define strings_type 1106 -#define list_type 1107 -#define listcomp_type 1108 -#define tuple_type 1109 -#define group_type 1110 -#define genexp_type 1111 -#define set_type 1112 -#define setcomp_type 1113 -#define dict_type 1114 -#define dictcomp_type 1115 -#define double_starred_kvpairs_type 1116 -#define double_starred_kvpair_type 1117 -#define kvpair_type 1118 -#define for_if_clauses_type 1119 -#define for_if_clause_type 1120 -#define yield_expr_type 1121 -#define arguments_type 1122 -#define args_type 1123 -#define kwargs_type 1124 -#define starred_expression_type 1125 -#define kwarg_or_starred_type 1126 -#define kwarg_or_double_starred_type 1127 -#define star_targets_type 1128 -#define star_targets_seq_type 1129 -#define star_target_type 1130 -#define star_atom_type 1131 -#define single_target_type 1132 -#define single_subscript_attribute_target_type 1133 -#define del_targets_type 1134 -#define del_target_type 1135 -#define del_t_atom_type 1136 -#define del_target_end_type 1137 -#define targets_type 1138 -#define target_type 1139 -#define t_primary_type 1140 // Left-recursive -#define t_lookahead_type 1141 -#define t_atom_type 1142 -#define incorrect_arguments_type 1143 -#define invalid_kwarg_type 1144 -#define invalid_named_expression_type 1145 -#define invalid_assignment_type 1146 -#define invalid_block_type 1147 -#define invalid_comprehension_type 1148 -#define invalid_dict_comprehension_type 1149 -#define invalid_parameters_type 1150 -#define invalid_star_etc_type 1151 -#define invalid_lambda_star_etc_type 1152 -#define invalid_double_type_comments_type 1153 -#define invalid_del_target_type 1154 -#define invalid_import_from_targets_type 1155 -#define _loop0_1_type 1156 -#define _loop0_2_type 1157 -#define _loop0_4_type 1158 -#define _gather_3_type 1159 -#define _loop0_6_type 1160 -#define _gather_5_type 1161 -#define _loop0_8_type 1162 -#define _gather_7_type 1163 -#define _loop0_10_type 1164 -#define _gather_9_type 1165 -#define _loop1_11_type 1166 -#define _loop0_13_type 1167 -#define _gather_12_type 1168 -#define _tmp_14_type 1169 -#define _tmp_15_type 1170 -#define _tmp_16_type 1171 -#define _tmp_17_type 1172 -#define _tmp_18_type 1173 -#define _tmp_19_type 1174 -#define _tmp_20_type 1175 -#define _tmp_21_type 1176 -#define _loop1_22_type 1177 -#define _tmp_23_type 1178 -#define _tmp_24_type 1179 -#define _loop0_26_type 1180 -#define _gather_25_type 1181 -#define _loop0_28_type 1182 -#define _gather_27_type 1183 -#define _tmp_29_type 1184 -#define _loop0_30_type 1185 -#define _loop1_31_type 1186 -#define _loop0_33_type 1187 -#define _gather_32_type 1188 -#define _tmp_34_type 1189 -#define _loop0_36_type 1190 -#define _gather_35_type 1191 -#define _tmp_37_type 1192 -#define _loop0_39_type 1193 -#define _gather_38_type 1194 -#define _loop0_41_type 1195 -#define _gather_40_type 1196 -#define _loop0_43_type 1197 -#define _gather_42_type 1198 -#define _loop0_45_type 1199 -#define _gather_44_type 1200 -#define _tmp_46_type 1201 -#define _loop1_47_type 1202 -#define _tmp_48_type 1203 -#define _tmp_49_type 1204 -#define _tmp_50_type 1205 -#define _tmp_51_type 1206 -#define _tmp_52_type 1207 -#define _loop0_53_type 1208 -#define _loop0_54_type 1209 -#define _loop0_55_type 1210 -#define _loop1_56_type 1211 -#define _loop0_57_type 1212 -#define _loop1_58_type 1213 -#define _loop1_59_type 1214 -#define _loop1_60_type 1215 -#define _loop0_61_type 1216 -#define _loop1_62_type 1217 -#define _loop0_63_type 1218 -#define _loop1_64_type 1219 -#define _loop0_65_type 1220 -#define _loop1_66_type 1221 -#define _loop1_67_type 1222 -#define _tmp_68_type 1223 -#define _loop0_70_type 1224 -#define _gather_69_type 1225 -#define _loop1_71_type 1226 -#define _loop0_73_type 1227 -#define _gather_72_type 1228 -#define _loop1_74_type 1229 -#define _loop0_75_type 1230 -#define _loop0_76_type 1231 -#define _loop0_77_type 1232 -#define _loop1_78_type 1233 -#define _loop0_79_type 1234 -#define _loop1_80_type 1235 -#define _loop1_81_type 1236 -#define _loop1_82_type 1237 -#define _loop0_83_type 1238 -#define _loop1_84_type 1239 -#define _loop0_85_type 1240 -#define _loop1_86_type 1241 -#define _loop0_87_type 1242 -#define _loop1_88_type 1243 -#define _loop1_89_type 1244 -#define _loop1_90_type 1245 -#define _loop1_91_type 1246 -#define _tmp_92_type 1247 -#define _loop0_94_type 1248 -#define _gather_93_type 1249 -#define _tmp_95_type 1250 -#define _tmp_96_type 1251 -#define _tmp_97_type 1252 -#define _tmp_98_type 1253 -#define _loop1_99_type 1254 -#define _tmp_100_type 1255 -#define _tmp_101_type 1256 -#define _loop0_103_type 1257 -#define _gather_102_type 1258 -#define _loop1_104_type 1259 -#define _loop0_105_type 1260 -#define _loop0_106_type 1261 -#define _tmp_107_type 1262 -#define _tmp_108_type 1263 -#define _loop0_110_type 1264 -#define _gather_109_type 1265 -#define _loop0_112_type 1266 -#define _gather_111_type 1267 -#define _loop0_114_type 1268 -#define _gather_113_type 1269 -#define _loop0_116_type 1270 -#define _gather_115_type 1271 -#define _loop0_117_type 1272 -#define _loop0_119_type 1273 -#define _gather_118_type 1274 -#define _tmp_120_type 1275 -#define _loop0_122_type 1276 -#define _gather_121_type 1277 -#define _loop0_124_type 1278 -#define _gather_123_type 1279 -#define _tmp_125_type 1280 -#define _loop0_126_type 1281 -#define _tmp_127_type 1282 -#define _loop0_128_type 1283 -#define _loop0_129_type 1284 -#define _tmp_130_type 1285 -#define _tmp_131_type 1286 -#define _loop0_132_type 1287 -#define _tmp_133_type 1288 -#define _tmp_134_type 1289 -#define _tmp_135_type 1290 -#define _tmp_136_type 1291 -#define _tmp_137_type 1292 -#define _tmp_138_type 1293 -#define _tmp_139_type 1294 -#define _tmp_140_type 1295 -#define _tmp_141_type 1296 -#define _tmp_142_type 1297 -#define _tmp_143_type 1298 -#define _tmp_144_type 1299 -#define _tmp_145_type 1300 -#define _tmp_146_type 1301 -#define _tmp_147_type 1302 -#define _tmp_148_type 1303 -#define _loop1_149_type 1304 -#define _tmp_150_type 1305 -#define _tmp_151_type 1306 +#define lambda_params_type 1069 +#define lambda_parameters_type 1070 +#define lambda_slash_no_default_type 1071 +#define lambda_slash_with_default_type 1072 +#define lambda_star_etc_type 1073 +#define lambda_kwds_type 1074 +#define lambda_param_no_default_type 1075 +#define lambda_param_with_default_type 1076 +#define lambda_param_maybe_default_type 1077 +#define lambda_param_type 1078 +#define disjunction_type 1079 +#define conjunction_type 1080 +#define inversion_type 1081 +#define comparison_type 1082 +#define compare_op_bitwise_or_pair_type 1083 +#define eq_bitwise_or_type 1084 +#define noteq_bitwise_or_type 1085 +#define lte_bitwise_or_type 1086 +#define lt_bitwise_or_type 1087 +#define gte_bitwise_or_type 1088 +#define gt_bitwise_or_type 1089 +#define notin_bitwise_or_type 1090 +#define in_bitwise_or_type 1091 +#define isnot_bitwise_or_type 1092 +#define is_bitwise_or_type 1093 +#define bitwise_or_type 1094 // Left-recursive +#define bitwise_xor_type 1095 // Left-recursive +#define bitwise_and_type 1096 // Left-recursive +#define shift_expr_type 1097 // Left-recursive +#define sum_type 1098 // Left-recursive +#define term_type 1099 // Left-recursive +#define factor_type 1100 +#define power_type 1101 +#define await_primary_type 1102 +#define primary_type 1103 // Left-recursive +#define slices_type 1104 +#define slice_type 1105 +#define atom_type 1106 +#define strings_type 1107 +#define list_type 1108 +#define listcomp_type 1109 +#define tuple_type 1110 +#define group_type 1111 +#define genexp_type 1112 +#define set_type 1113 +#define setcomp_type 1114 +#define dict_type 1115 +#define dictcomp_type 1116 +#define double_starred_kvpairs_type 1117 +#define double_starred_kvpair_type 1118 +#define kvpair_type 1119 +#define for_if_clauses_type 1120 +#define for_if_clause_type 1121 +#define yield_expr_type 1122 +#define arguments_type 1123 +#define args_type 1124 +#define kwargs_type 1125 +#define starred_expression_type 1126 +#define kwarg_or_starred_type 1127 +#define kwarg_or_double_starred_type 1128 +#define star_targets_type 1129 +#define star_targets_seq_type 1130 +#define star_target_type 1131 +#define star_atom_type 1132 +#define single_target_type 1133 +#define single_subscript_attribute_target_type 1134 +#define del_targets_type 1135 +#define del_target_type 1136 +#define del_t_atom_type 1137 +#define del_target_end_type 1138 +#define targets_type 1139 +#define target_type 1140 +#define t_primary_type 1141 // Left-recursive +#define t_lookahead_type 1142 +#define t_atom_type 1143 +#define incorrect_arguments_type 1144 +#define invalid_kwarg_type 1145 +#define invalid_named_expression_type 1146 +#define invalid_assignment_type 1147 +#define invalid_block_type 1148 +#define invalid_comprehension_type 1149 +#define invalid_dict_comprehension_type 1150 +#define invalid_parameters_type 1151 +#define invalid_lambda_parameters_type 1152 +#define invalid_star_etc_type 1153 +#define invalid_lambda_star_etc_type 1154 +#define invalid_double_type_comments_type 1155 +#define invalid_del_target_type 1156 +#define invalid_import_from_targets_type 1157 +#define _loop0_1_type 1158 +#define _loop0_2_type 1159 +#define _loop0_4_type 1160 +#define _gather_3_type 1161 +#define _loop0_6_type 1162 +#define _gather_5_type 1163 +#define _loop0_8_type 1164 +#define _gather_7_type 1165 +#define _loop0_10_type 1166 +#define _gather_9_type 1167 +#define _loop1_11_type 1168 +#define _loop0_13_type 1169 +#define _gather_12_type 1170 +#define _tmp_14_type 1171 +#define _tmp_15_type 1172 +#define _tmp_16_type 1173 +#define _tmp_17_type 1174 +#define _tmp_18_type 1175 +#define _tmp_19_type 1176 +#define _tmp_20_type 1177 +#define _tmp_21_type 1178 +#define _loop1_22_type 1179 +#define _tmp_23_type 1180 +#define _tmp_24_type 1181 +#define _loop0_26_type 1182 +#define _gather_25_type 1183 +#define _loop0_28_type 1184 +#define _gather_27_type 1185 +#define _tmp_29_type 1186 +#define _loop0_30_type 1187 +#define _loop1_31_type 1188 +#define _loop0_33_type 1189 +#define _gather_32_type 1190 +#define _tmp_34_type 1191 +#define _loop0_36_type 1192 +#define _gather_35_type 1193 +#define _tmp_37_type 1194 +#define _loop0_39_type 1195 +#define _gather_38_type 1196 +#define _loop0_41_type 1197 +#define _gather_40_type 1198 +#define _loop0_43_type 1199 +#define _gather_42_type 1200 +#define _loop0_45_type 1201 +#define _gather_44_type 1202 +#define _tmp_46_type 1203 +#define _loop1_47_type 1204 +#define _tmp_48_type 1205 +#define _tmp_49_type 1206 +#define _tmp_50_type 1207 +#define _tmp_51_type 1208 +#define _tmp_52_type 1209 +#define _loop0_53_type 1210 +#define _loop0_54_type 1211 +#define _loop0_55_type 1212 +#define _loop1_56_type 1213 +#define _loop0_57_type 1214 +#define _loop1_58_type 1215 +#define _loop1_59_type 1216 +#define _loop1_60_type 1217 +#define _loop0_61_type 1218 +#define _loop1_62_type 1219 +#define _loop0_63_type 1220 +#define _loop1_64_type 1221 +#define _loop0_65_type 1222 +#define _loop1_66_type 1223 +#define _loop1_67_type 1224 +#define _tmp_68_type 1225 +#define _loop0_70_type 1226 +#define _gather_69_type 1227 +#define _loop1_71_type 1228 +#define _loop0_73_type 1229 +#define _gather_72_type 1230 +#define _loop1_74_type 1231 +#define _loop0_75_type 1232 +#define _loop0_76_type 1233 +#define _loop0_77_type 1234 +#define _loop1_78_type 1235 +#define _loop0_79_type 1236 +#define _loop1_80_type 1237 +#define _loop1_81_type 1238 +#define _loop1_82_type 1239 +#define _loop0_83_type 1240 +#define _loop1_84_type 1241 +#define _loop0_85_type 1242 +#define _loop1_86_type 1243 +#define _loop0_87_type 1244 +#define _loop1_88_type 1245 +#define _loop1_89_type 1246 +#define _loop1_90_type 1247 +#define _loop1_91_type 1248 +#define _tmp_92_type 1249 +#define _loop0_94_type 1250 +#define _gather_93_type 1251 +#define _tmp_95_type 1252 +#define _tmp_96_type 1253 +#define _tmp_97_type 1254 +#define _tmp_98_type 1255 +#define _loop1_99_type 1256 +#define _tmp_100_type 1257 +#define _tmp_101_type 1258 +#define _loop0_103_type 1259 +#define _gather_102_type 1260 +#define _loop1_104_type 1261 +#define _loop0_105_type 1262 +#define _loop0_106_type 1263 +#define _tmp_107_type 1264 +#define _tmp_108_type 1265 +#define _loop0_110_type 1266 +#define _gather_109_type 1267 +#define _loop0_112_type 1268 +#define _gather_111_type 1269 +#define _loop0_114_type 1270 +#define _gather_113_type 1271 +#define _loop0_116_type 1272 +#define _gather_115_type 1273 +#define _loop0_117_type 1274 +#define _loop0_119_type 1275 +#define _gather_118_type 1276 +#define _tmp_120_type 1277 +#define _loop0_122_type 1278 +#define _gather_121_type 1279 +#define _loop0_124_type 1280 +#define _gather_123_type 1281 +#define _tmp_125_type 1282 +#define _loop0_126_type 1283 +#define _tmp_127_type 1284 +#define _loop0_128_type 1285 +#define _loop0_129_type 1286 +#define _tmp_130_type 1287 +#define _tmp_131_type 1288 +#define _loop0_132_type 1289 +#define _tmp_133_type 1290 +#define _loop0_134_type 1291 +#define _tmp_135_type 1292 +#define _tmp_136_type 1293 +#define _tmp_137_type 1294 +#define _tmp_138_type 1295 +#define _tmp_139_type 1296 +#define _tmp_140_type 1297 +#define _tmp_141_type 1298 +#define _tmp_142_type 1299 +#define _tmp_143_type 1300 +#define _tmp_144_type 1301 +#define _tmp_145_type 1302 +#define _tmp_146_type 1303 +#define _tmp_147_type 1304 +#define _tmp_148_type 1305 +#define _tmp_149_type 1306 +#define _tmp_150_type 1307 +#define _loop1_151_type 1308 +#define _loop1_152_type 1309 +#define _tmp_153_type 1310 +#define _tmp_154_type 1311 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -452,6 +457,7 @@ static expr_ty annotated_rhs_rule(Parser *p); static expr_ty expressions_rule(Parser *p); static expr_ty expression_rule(Parser *p); static expr_ty lambdef_rule(Parser *p); +static arguments_ty lambda_params_rule(Parser *p); static arguments_ty lambda_parameters_rule(Parser *p); static asdl_seq* lambda_slash_no_default_rule(Parser *p); static SlashWithDefault* lambda_slash_with_default_rule(Parser *p); @@ -534,6 +540,7 @@ static void *invalid_block_rule(Parser *p); static void *invalid_comprehension_rule(Parser *p); static void *invalid_dict_comprehension_rule(Parser *p); static void *invalid_parameters_rule(Parser *p); +static void *invalid_lambda_parameters_rule(Parser *p); static void *invalid_star_etc_rule(Parser *p); static void *invalid_lambda_star_etc_rule(Parser *p); static void *invalid_double_type_comments_rule(Parser *p); @@ -672,7 +679,7 @@ static void *_tmp_130_rule(Parser *p); static void *_tmp_131_rule(Parser *p); static asdl_seq *_loop0_132_rule(Parser *p); static void *_tmp_133_rule(Parser *p); -static void *_tmp_134_rule(Parser *p); +static asdl_seq *_loop0_134_rule(Parser *p); static void *_tmp_135_rule(Parser *p); static void *_tmp_136_rule(Parser *p); static void *_tmp_137_rule(Parser *p); @@ -687,9 +694,12 @@ static void *_tmp_145_rule(Parser *p); static void *_tmp_146_rule(Parser *p); static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); -static asdl_seq *_loop1_149_rule(Parser *p); +static void *_tmp_149_rule(Parser *p); static void *_tmp_150_rule(Parser *p); -static void *_tmp_151_rule(Parser *p); +static asdl_seq *_loop1_151_rule(Parser *p); +static asdl_seq *_loop1_152_rule(Parser *p); +static void *_tmp_153_rule(Parser *p); +static void *_tmp_154_rule(Parser *p); // file: statements? $ @@ -6972,7 +6982,7 @@ expression_rule(Parser *p) return _res; } -// lambdef: 'lambda' lambda_parameters? ':' expression +// lambdef: 'lambda' lambda_params? ':' expression static expr_ty lambdef_rule(Parser *p) { @@ -6992,12 +7002,12 @@ lambdef_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro - { // 'lambda' lambda_parameters? ':' expression + { // 'lambda' lambda_params? ':' expression if (p->error_indicator) { D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_parameters? ':' expression")); + D(fprintf(stderr, "%*c> lambdef[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); Token * _keyword; Token * _literal; void *a; @@ -7005,14 +7015,14 @@ lambdef_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 524)) // token='lambda' && - (a = lambda_parameters_rule(p), 1) // lambda_parameters? + (a = lambda_params_rule(p), 1) // lambda_params? && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (b = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_parameters? ':' expression")); + D(fprintf(stderr, "%*c+ lambdef[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' expression")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { D(p->level--); @@ -7032,7 +7042,62 @@ lambdef_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s lambdef[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_parameters? ':' expression")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' expression")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + +// lambda_params: invalid_lambda_parameters | lambda_parameters +static arguments_ty +lambda_params_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + arguments_ty _res = NULL; + int _mark = p->mark; + { // invalid_lambda_parameters + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); + void *invalid_lambda_parameters_var; + if ( + (invalid_lambda_parameters_var = invalid_lambda_parameters_rule(p)) // invalid_lambda_parameters + ) + { + D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_parameters")); + _res = invalid_lambda_parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_parameters")); + } + { // lambda_parameters + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> lambda_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); + arguments_ty lambda_parameters_var; + if ( + (lambda_parameters_var = lambda_parameters_rule(p)) // lambda_parameters + ) + { + D(fprintf(stderr, "%*c+ lambda_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_parameters")); + _res = lambda_parameters_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_parameters")); } _res = NULL; done: @@ -14997,6 +15062,54 @@ invalid_parameters_rule(Parser *p) return _res; } +// invalid_lambda_parameters: +// | lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default +static void * +invalid_lambda_parameters_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); + asdl_seq * _loop0_134_var; + void *_tmp_135_var; + arg_ty lambda_param_no_default_var; + if ( + (_loop0_134_var = _loop0_134_rule(p)) // lambda_param_no_default* + && + (_tmp_135_var = _tmp_135_rule(p)) // lambda_slash_with_default | lambda_param_with_default+ + && + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); + _res = RAISE_SYNTAX_ERROR ( "non-default argument follows default argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + D(p->level--); + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + // invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT static void * invalid_star_etc_rule(Parser *p) @@ -15015,11 +15128,11 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); Token * _literal; - void *_tmp_134_var; + void *_tmp_136_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_134_var = _tmp_134_rule(p)) // ')' | ',' (')' | '**') + (_tmp_136_var = _tmp_136_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -15089,11 +15202,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_135_var; + void *_tmp_137_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_135_var = _tmp_135_rule(p)) // ':' | ',' (':' | '**') + (_tmp_137_var = _tmp_137_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -16503,12 +16616,12 @@ _loop1_22_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_136_var; + void *_tmp_138_var; while ( - (_tmp_136_var = _tmp_136_rule(p)) // star_targets '=' + (_tmp_138_var = _tmp_138_rule(p)) // star_targets '=' ) { - _res = _tmp_136_var; + _res = _tmp_138_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -16956,12 +17069,12 @@ _loop0_30_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_137_var; + void *_tmp_139_var; while ( - (_tmp_137_var = _tmp_137_rule(p)) // '.' | '...' + (_tmp_139_var = _tmp_139_rule(p)) // '.' | '...' ) { - _res = _tmp_137_var; + _res = _tmp_139_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -17022,12 +17135,12 @@ _loop1_31_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_138_var; + void *_tmp_140_var; while ( - (_tmp_138_var = _tmp_138_rule(p)) // '.' | '...' + (_tmp_140_var = _tmp_140_rule(p)) // '.' | '...' ) { - _res = _tmp_138_var; + _res = _tmp_140_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19154,12 +19267,12 @@ _loop1_67_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_139_var; + void *_tmp_141_var; while ( - (_tmp_139_var = _tmp_139_rule(p)) // '@' named_expression NEWLINE + (_tmp_141_var = _tmp_141_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_139_var; + _res = _tmp_141_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19386,12 +19499,12 @@ _loop1_71_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_140_var; + void *_tmp_142_var; while ( - (_tmp_140_var = _tmp_140_rule(p)) // ',' star_expression + (_tmp_142_var = _tmp_142_rule(p)) // ',' star_expression ) { - _res = _tmp_140_var; + _res = _tmp_142_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -19571,12 +19684,12 @@ _loop1_74_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_141_var; + void *_tmp_143_var; while ( - (_tmp_141_var = _tmp_141_rule(p)) // ',' expression + (_tmp_143_var = _tmp_143_rule(p)) // ',' expression ) { - _res = _tmp_141_var; + _res = _tmp_143_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -20601,12 +20714,12 @@ _loop1_89_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_142_var; + void *_tmp_144_var; while ( - (_tmp_142_var = _tmp_142_rule(p)) // 'or' conjunction + (_tmp_144_var = _tmp_144_rule(p)) // 'or' conjunction ) { - _res = _tmp_142_var; + _res = _tmp_144_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -20672,12 +20785,12 @@ _loop1_90_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_143_var; + void *_tmp_145_var; while ( - (_tmp_143_var = _tmp_143_rule(p)) // 'and' inversion + (_tmp_145_var = _tmp_145_rule(p)) // 'and' inversion ) { - _res = _tmp_143_var; + _res = _tmp_145_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21593,12 +21706,12 @@ _loop0_105_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_144_var; + void *_tmp_146_var; while ( - (_tmp_144_var = _tmp_144_rule(p)) // 'if' disjunction + (_tmp_146_var = _tmp_146_rule(p)) // 'if' disjunction ) { - _res = _tmp_144_var; + _res = _tmp_146_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -21659,12 +21772,12 @@ _loop0_106_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_145_var; + void *_tmp_147_var; while ( - (_tmp_145_var = _tmp_145_rule(p)) // 'if' disjunction + (_tmp_147_var = _tmp_147_rule(p)) // 'if' disjunction ) { - _res = _tmp_145_var; + _res = _tmp_147_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22269,12 +22382,12 @@ _loop0_117_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_146_var; + void *_tmp_148_var; while ( - (_tmp_146_var = _tmp_146_rule(p)) // ',' star_target + (_tmp_148_var = _tmp_148_rule(p)) // ',' star_target ) { - _res = _tmp_146_var; + _res = _tmp_148_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22878,12 +22991,12 @@ _loop0_128_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_147_var; + void *_tmp_149_var; while ( - (_tmp_147_var = _tmp_147_rule(p)) // star_targets '=' + (_tmp_149_var = _tmp_149_rule(p)) // star_targets '=' ) { - _res = _tmp_147_var; + _res = _tmp_149_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -22944,12 +23057,12 @@ _loop0_129_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_148_var; + void *_tmp_150_var; while ( - (_tmp_148_var = _tmp_148_rule(p)) // star_targets '=' + (_tmp_150_var = _tmp_150_rule(p)) // star_targets '=' ) { - _res = _tmp_148_var; + _res = _tmp_150_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -23214,13 +23327,13 @@ _tmp_133_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _tmp_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_149_var; + asdl_seq * _loop1_151_var; if ( - (_loop1_149_var = _loop1_149_rule(p)) // param_with_default+ + (_loop1_151_var = _loop1_151_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ _tmp_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_149_var; + _res = _loop1_151_var; goto done; } p->mark = _mark; @@ -23233,9 +23346,130 @@ _tmp_133_rule(Parser *p) return _res; } -// _tmp_134: ')' | ',' (')' | '**') +// _loop0_134: lambda_param_no_default +static asdl_seq * +_loop0_134_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + ssize_t _children_capacity = 1; + ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq); + D(p->level--); + return _seq; +} + +// _tmp_135: lambda_slash_with_default | lambda_param_with_default+ +static void * +_tmp_135_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_with_default + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + { // lambda_param_with_default+ + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + asdl_seq * _loop1_152_var; + if ( + (_loop1_152_var = _loop1_152_rule(p)) // lambda_param_with_default+ + ) + { + D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); + _res = _loop1_152_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default+")); + } + _res = NULL; + done: + D(p->level--); + return _res; +} + +// _tmp_136: ')' | ',' (')' | '**') static void * -_tmp_134_rule(Parser *p) +_tmp_136_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23249,18 +23483,18 @@ _tmp_134_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -23268,21 +23502,21 @@ _tmp_134_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_150_var; + void *_tmp_153_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_150_var = _tmp_150_rule(p)) // ')' | '**' + (_tmp_153_var = _tmp_153_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_150_var); + D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_153_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -23291,9 +23525,9 @@ _tmp_134_rule(Parser *p) return _res; } -// _tmp_135: ':' | ',' (':' | '**') +// _tmp_137: ':' | ',' (':' | '**') static void * -_tmp_135_rule(Parser *p) +_tmp_137_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23307,18 +23541,18 @@ _tmp_135_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -23326,21 +23560,21 @@ _tmp_135_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_151_var; + void *_tmp_154_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_151_var = _tmp_151_rule(p)) // ':' | '**' + (_tmp_154_var = _tmp_154_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_151_var); + D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_154_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -23349,9 +23583,9 @@ _tmp_135_rule(Parser *p) return _res; } -// _tmp_136: star_targets '=' +// _tmp_138: star_targets '=' static void * -_tmp_136_rule(Parser *p) +_tmp_138_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23365,7 +23599,7 @@ _tmp_136_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -23374,7 +23608,7 @@ _tmp_136_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23384,7 +23618,7 @@ _tmp_136_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -23393,9 +23627,9 @@ _tmp_136_rule(Parser *p) return _res; } -// _tmp_137: '.' | '...' +// _tmp_139: '.' | '...' static void * -_tmp_137_rule(Parser *p) +_tmp_139_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23409,18 +23643,18 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23428,18 +23662,18 @@ _tmp_137_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -23448,9 +23682,9 @@ _tmp_137_rule(Parser *p) return _res; } -// _tmp_138: '.' | '...' +// _tmp_140: '.' | '...' static void * -_tmp_138_rule(Parser *p) +_tmp_140_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23464,18 +23698,18 @@ _tmp_138_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -23483,18 +23717,18 @@ _tmp_138_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -23503,9 +23737,9 @@ _tmp_138_rule(Parser *p) return _res; } -// _tmp_139: '@' named_expression NEWLINE +// _tmp_141: '@' named_expression NEWLINE static void * -_tmp_139_rule(Parser *p) +_tmp_141_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23519,7 +23753,7 @@ _tmp_139_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -23531,7 +23765,7 @@ _tmp_139_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23541,7 +23775,7 @@ _tmp_139_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -23550,9 +23784,9 @@ _tmp_139_rule(Parser *p) return _res; } -// _tmp_140: ',' star_expression +// _tmp_142: ',' star_expression static void * -_tmp_140_rule(Parser *p) +_tmp_142_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23566,7 +23800,7 @@ _tmp_140_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -23575,7 +23809,7 @@ _tmp_140_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23585,7 +23819,7 @@ _tmp_140_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -23594,9 +23828,9 @@ _tmp_140_rule(Parser *p) return _res; } -// _tmp_141: ',' expression +// _tmp_143: ',' expression static void * -_tmp_141_rule(Parser *p) +_tmp_143_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23610,7 +23844,7 @@ _tmp_141_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -23619,7 +23853,7 @@ _tmp_141_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23629,7 +23863,7 @@ _tmp_141_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -23638,9 +23872,9 @@ _tmp_141_rule(Parser *p) return _res; } -// _tmp_142: 'or' conjunction +// _tmp_144: 'or' conjunction static void * -_tmp_142_rule(Parser *p) +_tmp_144_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23654,7 +23888,7 @@ _tmp_142_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -23663,7 +23897,7 @@ _tmp_142_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23673,7 +23907,7 @@ _tmp_142_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -23682,9 +23916,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: 'and' inversion +// _tmp_145: 'and' inversion static void * -_tmp_143_rule(Parser *p) +_tmp_145_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23698,7 +23932,7 @@ _tmp_143_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -23707,7 +23941,7 @@ _tmp_143_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23717,7 +23951,7 @@ _tmp_143_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -23726,9 +23960,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'if' disjunction +// _tmp_146: 'if' disjunction static void * -_tmp_144_rule(Parser *p) +_tmp_146_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23742,7 +23976,7 @@ _tmp_144_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -23751,7 +23985,7 @@ _tmp_144_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23761,7 +23995,7 @@ _tmp_144_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -23770,9 +24004,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: 'if' disjunction +// _tmp_147: 'if' disjunction static void * -_tmp_145_rule(Parser *p) +_tmp_147_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23786,7 +24020,7 @@ _tmp_145_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -23795,7 +24029,7 @@ _tmp_145_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23805,7 +24039,7 @@ _tmp_145_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -23814,9 +24048,9 @@ _tmp_145_rule(Parser *p) return _res; } -// _tmp_146: ',' star_target +// _tmp_148: ',' star_target static void * -_tmp_146_rule(Parser *p) +_tmp_148_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23830,7 +24064,7 @@ _tmp_146_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -23839,7 +24073,7 @@ _tmp_146_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -23849,7 +24083,7 @@ _tmp_146_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -23858,9 +24092,9 @@ _tmp_146_rule(Parser *p) return _res; } -// _tmp_147: star_targets '=' +// _tmp_149: star_targets '=' static void * -_tmp_147_rule(Parser *p) +_tmp_149_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23874,7 +24108,7 @@ _tmp_147_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -23883,12 +24117,12 @@ _tmp_147_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -23897,9 +24131,9 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: star_targets '=' +// _tmp_150: star_targets '=' static void * -_tmp_148_rule(Parser *p) +_tmp_150_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23913,7 +24147,7 @@ _tmp_148_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -23922,12 +24156,12 @@ _tmp_148_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -23936,9 +24170,9 @@ _tmp_148_rule(Parser *p) return _res; } -// _loop1_149: param_with_default +// _loop1_151: param_with_default static asdl_seq * -_loop1_149_rule(Parser *p) +_loop1_151_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -23962,7 +24196,7 @@ _loop1_149_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _loop1_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -23984,7 +24218,7 @@ _loop1_149_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -24002,14 +24236,85 @@ _loop1_149_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_149_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_151_type, _seq); D(p->level--); return _seq; } -// _tmp_150: ')' | '**' +// _loop1_152: lambda_param_with_default +static asdl_seq * +_loop1_152_rule(Parser *p) +{ + D(p->level++); + if (p->error_indicator) { + D(p->level--); + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + ssize_t _children_capacity = 1; + ssize_t _n = 0; + { // lambda_param_with_default + if (p->error_indicator) { + D(p->level--); + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + ) + { + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + D(p->level--); + return NULL; + } + asdl_seq *_seq = _Py_asdl_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + D(p->level--); + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_152_type, _seq); + D(p->level--); + return _seq; +} + +// _tmp_153: ')' | '**' static void * -_tmp_150_rule(Parser *p) +_tmp_153_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24023,18 +24328,18 @@ _tmp_150_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -24042,18 +24347,18 @@ _tmp_150_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -24062,9 +24367,9 @@ _tmp_150_rule(Parser *p) return _res; } -// _tmp_151: ':' | '**' +// _tmp_154: ':' | '**' static void * -_tmp_151_rule(Parser *p) +_tmp_154_rule(Parser *p) { D(p->level++); if (p->error_indicator) { @@ -24078,18 +24383,18 @@ _tmp_151_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -24097,18 +24402,18 @@ _tmp_151_rule(Parser *p) D(p->level--); return NULL; } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; From webhook-mailer at python.org Wed Jun 10 11:39:20 2020 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Wed, 10 Jun 2020 15:39:20 -0000 Subject: [Python-checkins] bpo-36543: Revert "bpo-36543: Remove the xml.etree.cElementTree module." (GH-20117) Message-ID: https://github.com/python/cpython/commit/ec88e1bca81a167e6d5c0ac635e22f84298cb1df commit: ec88e1bca81a167e6d5c0ac635e22f84298cb1df branch: master author: Serhiy Storchaka committer: GitHub date: 2020-06-10T17:39:12+02:00 summary: bpo-36543: Revert "bpo-36543: Remove the xml.etree.cElementTree module." (GH-20117) * Revert "bpo-36543: Remove the xml.etree.cElementTree module. (GH-19108)" This reverts commit b33e52511a59c6da7132c226b7f7489b092a33eb. files: A Lib/xml/etree/cElementTree.py A Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst M Doc/library/xml.etree.elementtree.rst M Doc/whatsnew/3.9.rst M Lib/test/test_xml_etree_c.py diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 2085a85927e46..7725e4d158d42 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -15,6 +15,8 @@ for parsing and creating XML data. .. versionchanged:: 3.3 This module will use a fast implementation whenever available. + +.. deprecated:: 3.3 The :mod:`xml.etree.cElementTree` module is deprecated. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index b20cd14565ae1..67a83bc958457 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -826,11 +826,6 @@ Removed module have been removed. They were deprecated in Python 3.2. Use ``iter(x)`` or ``list(x)`` instead of ``x.getchildren()`` and ``x.iter()`` or ``list(x.iter())`` instead of ``x.getiterator()``. - The ``xml.etree.cElementTree`` module has been removed, - use the :mod:`xml.etree.ElementTree` module instead. - Since Python 3.3 the ``xml.etree.cElementTree`` module has been deprecated, - the ``xml.etree.ElementTree`` module uses a fast implementation whenever - available. (Contributed by Serhiy Storchaka in :issue:`36543`.) * The old :mod:`plistlib` API has been removed, it was deprecated since Python diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index 7437e13d0611c..e26e1714a540b 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -8,6 +8,9 @@ cET = import_fresh_module('xml.etree.ElementTree', fresh=['_elementtree']) +cET_alias = import_fresh_module('xml.etree.cElementTree', + fresh=['_elementtree', 'xml.etree'], + deprecated=True) @unittest.skipUnless(cET, 'requires _elementtree') @@ -167,6 +170,14 @@ def test_xmlpullparser_leaks(self): support.gc_collect() + at unittest.skipUnless(cET, 'requires _elementtree') +class TestAliasWorking(unittest.TestCase): + # Test that the cET alias module is alive + def test_alias_working(self): + e = cET_alias.Element('foo') + self.assertEqual(e.tag, 'foo') + + @unittest.skipUnless(cET, 'requires _elementtree') @support.cpython_only class TestAcceleratorImported(unittest.TestCase): @@ -175,6 +186,9 @@ def test_correct_import_cET(self): # SubElement is a function so it retains _elementtree as its module. self.assertEqual(cET.SubElement.__module__, '_elementtree') + def test_correct_import_cET_alias(self): + self.assertEqual(cET_alias.SubElement.__module__, '_elementtree') + def test_parser_comes_from_C(self): # The type of methods defined in Python code is types.FunctionType, # while the type of methods defined inside _elementtree is @@ -214,6 +228,7 @@ def test_main(): # Run the tests specific to the C implementation support.run_unittest( MiscTests, + TestAliasWorking, TestAcceleratorImported, SizeofTest, ) diff --git a/Lib/xml/etree/cElementTree.py b/Lib/xml/etree/cElementTree.py new file mode 100644 index 0000000000000..368e679189582 --- /dev/null +++ b/Lib/xml/etree/cElementTree.py @@ -0,0 +1,3 @@ +# Deprecated alias for xml.etree.ElementTree + +from xml.etree.ElementTree import * diff --git a/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst b/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst new file mode 100644 index 0000000000000..468c1ac9eee17 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-15-21-14-45.bpo-36543.Jt-eSX.rst @@ -0,0 +1 @@ +Restored the deprecated :mod:`xml.etree.cElementTree` module. From webhook-mailer at python.org Wed Jun 10 12:09:09 2020 From: webhook-mailer at python.org (scoder) Date: Wed, 10 Jun 2020 16:09:09 -0000 Subject: [Python-checkins] bpo-40703: Let PyType_FromSpec() set "type.__module__" only if it is not set yet. (GH-20273) Message-ID: https://github.com/python/cpython/commit/24b8bad6d30ae4fb37ee686a073adfa5308659f9 commit: 24b8bad6d30ae4fb37ee686a073adfa5308659f9 branch: master author: scoder committer: GitHub date: 2020-06-10T18:09:01+02:00 summary: bpo-40703: Let PyType_FromSpec() set "type.__module__" only if it is not set yet. (GH-20273) files: A Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst M Objects/typeobject.c diff --git a/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst b/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst new file mode 100644 index 0000000000000..5385a2d8dce45 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-05-20-19-11-12.bpo-40703.qQXfW8.rst @@ -0,0 +1,2 @@ +The PyType_FromSpec*() functions no longer overwrite the type's "__module__" attribute +if it is set via "Py_tp_members" or "Py_tp_gets