From webhook-mailer at python.org Fri Nov 1 11:47:23 2019 From: webhook-mailer at python.org (Petr Viktorin) Date: Fri, 01 Nov 2019 15:47:23 -0000 Subject: [Python-checkins] bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) Message-ID: https://github.com/python/cpython/commit/9bc94eca0c69a551f928692364a99e9b67c4a45b commit: 9bc94eca0c69a551f928692364a99e9b67c4a45b branch: master author: Petr Viktorin committer: GitHub date: 2019-11-01T16:47:05+01:00 summary: bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) This was never intented to be called manually from PyInit_*. Also, clarify PyState_RemoveModule return value. files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 46306b3917cce..57902a9c7f838 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -485,10 +485,21 @@ since multiple such modules can be created from a single definition. Only effective on modules created using single-phase initialization. + Python calls ``PyState_AddModule`` automatically after importing a module, + so it is unnecessary (but harmless) to call it from module initialization + code. An explicit call is needed only if the module's own init code + subsequently calls ``PyState_FindModule``. + The function is mainly intended for implementing alternative import + mechanisms (either by calling it directly, or by referring to its + implementation for details of the required state updates). + + Return 0 on success or -1 on failure. + .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. + Return 0 on success or -1 on failure. .. versionadded:: 3.3 From webhook-mailer at python.org Fri Nov 1 12:45:11 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Fri, 01 Nov 2019 16:45:11 -0000 Subject: [Python-checkins] Slightly improve plistlib test coverage. (GH-17025) Message-ID: https://github.com/python/cpython/commit/d0d9f7cfa36bafa4e1d9e73eb08835180d376df1 commit: d0d9f7cfa36bafa4e1d9e73eb08835180d376df1 branch: master author: Jon Janzen committer: Serhiy Storchaka date: 2019-11-01T18:45:01+02:00 summary: Slightly improve plistlib test coverage. (GH-17025) * Add missing test class (mistake in GH-4455) * Increase coverage with 4 more test cases * Rename neg_uid to huge_uid in test_modified_uid_huge * Replace test_main() with unittest.main() * Update plistlib docs files: M Doc/library/plistlib.rst M Lib/test/test_plistlib.py diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index 68320f1577710..6def72b3736b9 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -133,7 +133,7 @@ The following classes are available: encoded data, which contains UID (see PList manual). It has one attribute, :attr:`data`, which can be used to retrieve the int value - of the UID. :attr:`data` must be in the range `0 <= data <= 2**64`. + of the UID. :attr:`data` must be in the range `0 <= data < 2**64`. .. versionadded:: 3.8 diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index d3ef6f8ffe3a4..e82a53c533df0 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -503,6 +503,26 @@ def test_xml_encodings(self): pl2 = plistlib.loads(data) self.assertEqual(dict(pl), dict(pl2)) + def test_dump_invalid_format(self): + with self.assertRaises(ValueError): + plistlib.dumps({}, fmt="blah") + + def test_load_invalid_file(self): + with self.assertRaises(plistlib.InvalidFileException): + plistlib.loads(b"these are not plist file contents") + + def test_modified_uid_negative(self): + neg_uid = UID(1) + neg_uid.data = -1 # dodge the negative check in the constructor + with self.assertRaises(ValueError): + plistlib.dumps(neg_uid, fmt=plistlib.FMT_BINARY) + + def test_modified_uid_huge(self): + huge_uid = UID(1) + huge_uid.data = 2 ** 64 # dodge the size check in the constructor + with self.assertRaises(OverflowError): + plistlib.dumps(huge_uid, fmt=plistlib.FMT_BINARY) + class TestBinaryPlistlib(unittest.TestCase): @@ -655,9 +675,5 @@ def test__all__(self): support.check__all__(self, plistlib, blacklist=blacklist) -def test_main(): - support.run_unittest(TestPlistlib, TestKeyedArchive, MiscTestCase) - - if __name__ == '__main__': - test_main() + unittest.main() From webhook-mailer at python.org Fri Nov 1 20:53:50 2019 From: webhook-mailer at python.org (Larry Hastings) Date: Sat, 02 Nov 2019 00:53:50 -0000 Subject: [Python-checkins] Blurb release and pydoc topics for 3.5.9 final. Message-ID: https://github.com/python/cpython/commit/9f9afc19573a0191a00ee258f60b04d4172c14e9 commit: 9f9afc19573a0191a00ee258f60b04d4172c14e9 branch: 3.5 author: Larry Hastings committer: Larry Hastings date: 2019-11-01T16:01:12-07:00 summary: Blurb release and pydoc topics for 3.5.9 final. files: A Misc/NEWS.d/3.5.9.rst M Lib/pydoc_data/topics.py diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 6795324cad20a..1f001e34e6c74 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon Oct 28 23:07:04 2019 +# Autogenerated by Sphinx on Fri Nov 1 15:54:02 2019 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' diff --git a/Misc/NEWS.d/3.5.9.rst b/Misc/NEWS.d/3.5.9.rst new file mode 100644 index 0000000000000..563722d3b0902 --- /dev/null +++ b/Misc/NEWS.d/3.5.9.rst @@ -0,0 +1,11 @@ +.. bpo: 0 +.. date: 2019-11-01 +.. no changes: True +.. nonce: vvRpzs +.. release date: 2019-11-01 +.. section: Library + +There were no new changes in version 3.5.9. 3.5.9 was released +because of a CDN caching problem which resulted in some users +downloading a prerelease version of the 3.5.8 .xz source tarball. +3.5.9 is identical to the proper 3.5.8 release. From webhook-mailer at python.org Sat Nov 2 10:48:50 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 02 Nov 2019 14:48:50 -0000 Subject: [Python-checkins] [3.8] Slightly improve plistlib test coverage. (GH-17025) (GH-17028) Message-ID: https://github.com/python/cpython/commit/fe934e1d03bca6ca6dd1bf87fce1695eeac984ce commit: fe934e1d03bca6ca6dd1bf87fce1695eeac984ce branch: 3.8 author: Jon Janzen committer: Serhiy Storchaka date: 2019-11-02T16:48:22+02:00 summary: [3.8] Slightly improve plistlib test coverage. (GH-17025) (GH-17028) * Add missing test class (mistake in GH-4455) * Increase coverage with 4 more test cases * Rename neg_uid to huge_uid in test_modified_uid_huge * Replace test_main() with unittest.main() * Update plistlib docs. (cherry picked from commit d0d9f7cfa36bafa4e1d9e73eb08835180d376df1) Co-authored-by: Jon Janzen files: M Doc/library/plistlib.rst M Lib/test/test_plistlib.py diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index d84fcac0ef23d..9dfe3c8a0dc98 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -188,8 +188,8 @@ The following classes are available: Wraps an :class:`int`. This is used when reading or writing NSKeyedArchiver encoded data, which contains UID (see PList manual). - It has one attribute, :attr:`data` which can be used to retrieve the int value - of the UID. :attr:`data` must be in the range `0 <= data <= 2**64`. + It has one attribute, :attr:`data`, which can be used to retrieve the int value + of the UID. :attr:`data` must be in the range `0 <= data < 2**64`. .. versionadded:: 3.8 diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index 5c2d0265079a2..0d887e210dde5 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -505,6 +505,26 @@ def test_xml_encodings(self): pl2 = plistlib.loads(data) self.assertEqual(dict(pl), dict(pl2)) + def test_dump_invalid_format(self): + with self.assertRaises(ValueError): + plistlib.dumps({}, fmt="blah") + + def test_load_invalid_file(self): + with self.assertRaises(plistlib.InvalidFileException): + plistlib.loads(b"these are not plist file contents") + + def test_modified_uid_negative(self): + neg_uid = UID(1) + neg_uid.data = -1 # dodge the negative check in the constructor + with self.assertRaises(ValueError): + plistlib.dumps(neg_uid, fmt=plistlib.FMT_BINARY) + + def test_modified_uid_huge(self): + huge_uid = UID(1) + huge_uid.data = 2 ** 64 # dodge the size check in the constructor + with self.assertRaises(OverflowError): + plistlib.dumps(huge_uid, fmt=plistlib.FMT_BINARY) + class TestBinaryPlistlib(unittest.TestCase): @@ -748,9 +768,5 @@ def test__all__(self): support.check__all__(self, plistlib, blacklist=blacklist) -def test_main(): - support.run_unittest(TestPlistlib, TestPlistlibDeprecated, TestKeyedArchive, MiscTestCase) - - if __name__ == '__main__': - test_main() + unittest.main() From webhook-mailer at python.org Sat Nov 2 12:47:00 2019 From: webhook-mailer at python.org (Miss Skeleton (bot)) Date: Sat, 02 Nov 2019 16:47:00 -0000 Subject: [Python-checkins] bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Message-ID: https://github.com/python/cpython/commit/8d4fef4ee2a318097f429cf6cbd4fb2e430bb9da commit: 8d4fef4ee2a318097f429cf6cbd4fb2e430bb9da branch: master author: Ram Rachum committer: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-02T09:46:24-07:00 summary: bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Whenever I use `path.suffix` I have to check again whether it includes the dot or not. I decided to add it to the docstring so I won't have to keep checking. https://bugs.python.org/issue38422 Automerge-Triggered-By: @pitrou files: A Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst M Lib/pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 825533d8d5f97..d70fde0ea3b45 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -799,7 +799,11 @@ def name(self): @property def suffix(self): - """The final component's last suffix, if any.""" + """ + The final component's last suffix, if any. + + This includes the leading period. For example: '.txt' + """ name = self.name i = name.rfind('.') if 0 < i < len(name) - 1: @@ -809,7 +813,11 @@ def suffix(self): @property def suffixes(self): - """A list of the final component's suffixes, if any.""" + """ + A list of the final component's suffixes, if any. + + These include the leading periods. For example: ['.tar', '.gz'] + """ name = self.name if name.endswith('.'): return [] diff --git a/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst new file mode 100644 index 0000000000000..0958fe265db56 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst @@ -0,0 +1 @@ +Clarify docstrings of pathlib suffix(es) From webhook-mailer at python.org Sat Nov 2 13:04:14 2019 From: webhook-mailer at python.org (Miss Skeleton (bot)) Date: Sat, 02 Nov 2019 17:04:14 -0000 Subject: [Python-checkins] bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Message-ID: https://github.com/python/cpython/commit/aa1fee8ffb0fb77a873c69d311759081346f8f4a commit: aa1fee8ffb0fb77a873c69d311759081346f8f4a branch: 3.8 author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-02T10:04:10-07:00 summary: bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Whenever I use `path.suffix` I have to check again whether it includes the dot or not. I decided to add it to the docstring so I won't have to keep checking. https://bugs.python.org/issue38422 Automerge-Triggered-By: @pitrou (cherry picked from commit 8d4fef4ee2a318097f429cf6cbd4fb2e430bb9da) Co-authored-by: Ram Rachum files: A Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst M Lib/pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 70b011b0e8c4f..c42bde459b368 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -799,7 +799,11 @@ def name(self): @property def suffix(self): - """The final component's last suffix, if any.""" + """ + The final component's last suffix, if any. + + This includes the leading period. For example: '.txt' + """ name = self.name i = name.rfind('.') if 0 < i < len(name) - 1: @@ -809,7 +813,11 @@ def suffix(self): @property def suffixes(self): - """A list of the final component's suffixes, if any.""" + """ + A list of the final component's suffixes, if any. + + These include the leading periods. For example: ['.tar', '.gz'] + """ name = self.name if name.endswith('.'): return [] diff --git a/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst new file mode 100644 index 0000000000000..0958fe265db56 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst @@ -0,0 +1 @@ +Clarify docstrings of pathlib suffix(es) From webhook-mailer at python.org Sat Nov 2 13:04:22 2019 From: webhook-mailer at python.org (Miss Skeleton (bot)) Date: Sat, 02 Nov 2019 17:04:22 -0000 Subject: [Python-checkins] bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Message-ID: https://github.com/python/cpython/commit/72b874a2ac6a7c1931e8b60fb865dc57adb441ee commit: 72b874a2ac6a7c1931e8b60fb865dc57adb441ee branch: 3.7 author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-02T10:04:18-07:00 summary: bpo-38422: Clarify docstrings of pathlib suffix(es) (GH-16679) Whenever I use `path.suffix` I have to check again whether it includes the dot or not. I decided to add it to the docstring so I won't have to keep checking. https://bugs.python.org/issue38422 Automerge-Triggered-By: @pitrou (cherry picked from commit 8d4fef4ee2a318097f429cf6cbd4fb2e430bb9da) Co-authored-by: Ram Rachum files: A Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst M Lib/pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index af9747ba3cb99..d868254bc5512 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -797,7 +797,11 @@ def name(self): @property def suffix(self): - """The final component's last suffix, if any.""" + """ + The final component's last suffix, if any. + + This includes the leading period. For example: '.txt' + """ name = self.name i = name.rfind('.') if 0 < i < len(name) - 1: @@ -807,7 +811,11 @@ def suffix(self): @property def suffixes(self): - """A list of the final component's suffixes, if any.""" + """ + A list of the final component's suffixes, if any. + + These include the leading periods. For example: ['.tar', '.gz'] + """ name = self.name if name.endswith('.'): return [] diff --git a/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst new file mode 100644 index 0000000000000..0958fe265db56 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst @@ -0,0 +1 @@ +Clarify docstrings of pathlib suffix(es) From webhook-mailer at python.org Sat Nov 2 13:06:35 2019 From: webhook-mailer at python.org (Tim Peters) Date: Sat, 02 Nov 2019 17:06:35 -0000 Subject: [Python-checkins] Years overdue, explain why unreachable objects are moved. (GH-17030) Message-ID: https://github.com/python/cpython/commit/d9d3993d1dbb2de11e15dd243df8be81681c46e5 commit: d9d3993d1dbb2de11e15dd243df8be81681c46e5 branch: master author: Tim Peters committer: GitHub date: 2019-11-02T12:06:31-05:00 summary: Years overdue, explain why unreachable objects are moved. (GH-17030) files: M Modules/gcmodule.c diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 1307aa3dc12fd..b258a0f6e1180 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1087,7 +1087,8 @@ deduce_unreachable(PyGC_Head *base, PyGC_Head *unreachable) { * everything else (in base) to unreachable. * NOTE: This used to move the reachable objects into a reachable * set instead. But most things usually turn out to be reachable, - * so it's more efficient to move the unreachable things. + * so it's more efficient to move the unreachable things. See note + ^ [REACHABLE OR UNREACHABLE?} at the file end. */ gc_list_init(unreachable); move_unreachable(base, unreachable); // gc_prev is pointer again @@ -2183,3 +2184,39 @@ PyObject_GC_Del(void *op) } PyObject_FREE(g); } + +/* ------------------------------------------------------------------------ +Notes + +[REACHABLE OR UNREACHABLE?} + +It "sounds slick" to move the unreachable objects, until you think about +it - the reason it pays isn't actually obvious. + +Suppose we create objects A, B, C in that order. They appear in the young +generation in the same order. If B points to A, and C to B, and C is +reachable from outside, then the adjusted refcounts will be 0, 0, and 1 +respectively. + +When move_unreachable finds A, A is moved to the unreachable list. The +same for B when it's first encountered. Then C is traversed, B is moved +_back_ to the reachable list. B is eventually traversed, and then A is +moved back to the reachable list. + +So instead of not moving at all, the reachable objects B and A are moved +twice each. Why is this a win? A straightforward algorithm to move the +reachable objects instead would move A, B, and C once each. + +The key is that this dance leaves the objects in order C, B, A - it's +reversed from the original order. On all _subsequent_ scans, none of +them will move. Since most objects aren't in cycles, this can save an +unbounded number of moves across an unbounded number of later collections. +It can cost more only the first time the chain is scanned. + +Drawback: move_unreachable is also used to find out what's still trash +after finalizers may resurrect objects. In _that_ case most unreachable +objects will remain unreachable, so it would be more efficient to move +the reachable objects instead. But this is a one-time cost, probably not +worth complicating the code to speed just a little. +------------------------------------------------------------------------ */ + From webhook-mailer at python.org Sat Nov 2 15:09:45 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sat, 02 Nov 2019 19:09:45 -0000 Subject: [Python-checkins] Convert argument to snake_case (GH-16990) Message-ID: https://github.com/python/cpython/commit/99b7701978d1fdc81e10c31d1ad8cce2c0c2d848 commit: 99b7701978d1fdc81e10c31d1ad8cce2c0c2d848 branch: master author: ????? ?????????? committer: Raymond Hettinger date: 2019-11-02T12:09:14-07:00 summary: Convert argument to snake_case (GH-16990) files: M Doc/library/itertools.rst diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 8d134d4380659..3e5a673898106 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -766,9 +766,9 @@ which incur interpreter overhead. def dotproduct(vec1, vec2): return sum(map(operator.mul, vec1, vec2)) - def flatten(listOfLists): + def flatten(list_of_lists): "Flatten one level of nesting" - return chain.from_iterable(listOfLists) + return chain.from_iterable(list_of_lists) def repeatfunc(func, times=None, *args): """Repeat calls to func with specified arguments. From webhook-mailer at python.org Sun Nov 3 06:55:59 2019 From: webhook-mailer at python.org (Tal Einat) Date: Sun, 03 Nov 2019 11:55:59 -0000 Subject: [Python-checkins] bpo-38388: Document pickle protocol version 5 (GH-16639) Message-ID: https://github.com/python/cpython/commit/d0e0f5bf0c07ca025f54df21fd1df55ee430d9fc commit: d0e0f5bf0c07ca025f54df21fd1df55ee430d9fc branch: master author: Dima Tisnek committer: Tal Einat date: 2019-11-03T13:55:33+02:00 summary: bpo-38388: Document pickle protocol version 5 (GH-16639) files: M Doc/library/pickle.rst diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index eb58178e0e928..779b60ed4da00 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -136,7 +136,7 @@ The module :mod:`pickletools` contains tools for analyzing data streams generated by :mod:`pickle`. :mod:`pickletools` source code has extensive comments about opcodes used by pickle protocols. -There are currently 5 different protocols which can be used for pickling. +There are currently 6 different protocols which can be used for pickling. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. @@ -160,6 +160,10 @@ to read the pickle produced. Refer to :pep:`3154` for information about improvements brought by protocol 4. +* Protocol version 5 was added in Python 3.8. It adds support for out-of-band + data and speedup for in-band data. Refer to :pep:`574` for information about + improvements brought by protocol 5. + .. note:: Serialization is a more primitive notion than persistence; although :mod:`pickle` reads and writes file objects, it does not handle the issue of From webhook-mailer at python.org Sun Nov 3 07:03:23 2019 From: webhook-mailer at python.org (Miss Skeleton (bot)) Date: Sun, 03 Nov 2019 12:03:23 -0000 Subject: [Python-checkins] bpo-38388: Document pickle protocol version 5 (GH-16639) Message-ID: https://github.com/python/cpython/commit/87af51847b2fc911f2c1e82be58a7aa3bb5bd2ca commit: 87af51847b2fc911f2c1e82be58a7aa3bb5bd2ca branch: 3.8 author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-03T04:03:16-08:00 summary: bpo-38388: Document pickle protocol version 5 (GH-16639) (cherry picked from commit d0e0f5bf0c07ca025f54df21fd1df55ee430d9fc) Co-authored-by: Dima Tisnek files: M Doc/library/pickle.rst diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index eb58178e0e928..779b60ed4da00 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -136,7 +136,7 @@ The module :mod:`pickletools` contains tools for analyzing data streams generated by :mod:`pickle`. :mod:`pickletools` source code has extensive comments about opcodes used by pickle protocols. -There are currently 5 different protocols which can be used for pickling. +There are currently 6 different protocols which can be used for pickling. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. @@ -160,6 +160,10 @@ to read the pickle produced. Refer to :pep:`3154` for information about improvements brought by protocol 4. +* Protocol version 5 was added in Python 3.8. It adds support for out-of-band + data and speedup for in-band data. Refer to :pep:`574` for information about + improvements brought by protocol 5. + .. note:: Serialization is a more primitive notion than persistence; although :mod:`pickle` reads and writes file objects, it does not handle the issue of From webhook-mailer at python.org Mon Nov 4 00:47:06 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 04 Nov 2019 05:47:06 -0000 Subject: [Python-checkins] bpo-37759: Show output from var_access_benchmark (GH-17040) Message-ID: https://github.com/python/cpython/commit/1cdadf414b9934bba9294efa1f4b8d97eef08434 commit: 1cdadf414b9934bba9294efa1f4b8d97eef08434 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-03T21:47:01-08:00 summary: bpo-37759: Show output from var_access_benchmark (GH-17040) files: M Doc/whatsnew/3.8.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index e26709696f956..8338cb6cb4f4c 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -2152,6 +2152,55 @@ CPython bytecode changes Demos and Tools --------------- -* Added a benchmark script for timing various ways to access variables: - ``Tools/scripts/var_access_benchmark.py``. - (Contributed by Raymond Hettinger in :issue:`35884`.) +Added a benchmark script for timing various ways to access variables: +``Tools/scripts/var_access_benchmark.py``. +(Contributed by Raymond Hettinger in :issue:`35884`.) + +Here's a summary of performance improvements since Python 3.3: + +.. code-block:: none + + Python version 3.3 3.4 3.5 3.6 3.7 3.8 + -------------- --- --- --- --- --- --- + + Variable and attribute read access: + read_local 4.0 7.1 7.1 5.4 5.1 3.9 + read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.4 + read_global 13.3 15.5 19.0 14.3 13.6 7.6 + read_builtin 20.0 21.1 21.6 18.5 19.0 7.5 + read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.4 + read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.4 + read_instancevar 26.8 32.4 33.1 28.0 26.3 25.4 + read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.2 + read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.4 + read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.7 + + Variable and attribute write access: + write_local 4.6 8.7 9.3 5.5 5.3 4.3 + write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.7 + write_global 15.9 19.7 21.2 18.0 18.0 15.8 + write_classvar 81.9 92.9 96.0 104.6 102.1 39.2 + write_instancevar 36.4 44.6 45.8 40.0 38.9 35.5 + write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.7 + + Data structure read access: + read_list 19.2 24.2 24.5 20.8 20.8 19.0 + read_deque 19.9 24.7 25.5 20.2 20.6 19.8 + read_dict 19.7 24.3 25.7 22.3 23.0 21.0 + read_strdict 17.9 22.6 24.3 19.5 21.2 18.9 + + Data structure write access: + write_list 21.2 27.1 28.5 22.5 21.6 20.0 + write_deque 23.8 28.7 30.1 22.7 21.8 23.5 + write_dict 25.9 31.4 33.3 29.3 29.2 24.7 + write_strdict 22.9 28.4 29.9 27.5 25.2 23.1 + + Stack (or queue) operations: + list_append_pop 144.2 93.4 112.7 75.4 74.2 50.8 + deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.5 + deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.8 + + Timing loop: + loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3 + + (Measured from the macOS 64-bit builds found at python.org) From webhook-mailer at python.org Mon Nov 4 00:55:30 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 04 Nov 2019 05:55:30 -0000 Subject: [Python-checkins] bpo-37759: Show output from var_access_benchmark (GH-17040) (GH-17041) Message-ID: https://github.com/python/cpython/commit/f90e0d2371bc2bcab7bf5307cfd73571eb06b375 commit: f90e0d2371bc2bcab7bf5307cfd73571eb06b375 branch: 3.8 author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-03T21:55:22-08:00 summary: bpo-37759: Show output from var_access_benchmark (GH-17040) (GH-17041) (cherry picked from commit 1cdadf414b9934bba9294efa1f4b8d97eef08434) Co-authored-by: Raymond Hettinger files: M Doc/whatsnew/3.8.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index e50ccae954921..5c3d5a02b46f1 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -2154,6 +2154,55 @@ CPython bytecode changes Demos and Tools --------------- -* Added a benchmark script for timing various ways to access variables: - ``Tools/scripts/var_access_benchmark.py``. - (Contributed by Raymond Hettinger in :issue:`35884`.) +Added a benchmark script for timing various ways to access variables: +``Tools/scripts/var_access_benchmark.py``. +(Contributed by Raymond Hettinger in :issue:`35884`.) + +Here's a summary of performance improvements since Python 3.3: + +.. code-block:: none + + Python version 3.3 3.4 3.5 3.6 3.7 3.8 + -------------- --- --- --- --- --- --- + + Variable and attribute read access: + read_local 4.0 7.1 7.1 5.4 5.1 3.9 + read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.4 + read_global 13.3 15.5 19.0 14.3 13.6 7.6 + read_builtin 20.0 21.1 21.6 18.5 19.0 7.5 + read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.4 + read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.4 + read_instancevar 26.8 32.4 33.1 28.0 26.3 25.4 + read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.2 + read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.4 + read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.7 + + Variable and attribute write access: + write_local 4.6 8.7 9.3 5.5 5.3 4.3 + write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.7 + write_global 15.9 19.7 21.2 18.0 18.0 15.8 + write_classvar 81.9 92.9 96.0 104.6 102.1 39.2 + write_instancevar 36.4 44.6 45.8 40.0 38.9 35.5 + write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.7 + + Data structure read access: + read_list 19.2 24.2 24.5 20.8 20.8 19.0 + read_deque 19.9 24.7 25.5 20.2 20.6 19.8 + read_dict 19.7 24.3 25.7 22.3 23.0 21.0 + read_strdict 17.9 22.6 24.3 19.5 21.2 18.9 + + Data structure write access: + write_list 21.2 27.1 28.5 22.5 21.6 20.0 + write_deque 23.8 28.7 30.1 22.7 21.8 23.5 + write_dict 25.9 31.4 33.3 29.3 29.2 24.7 + write_strdict 22.9 28.4 29.9 27.5 25.2 23.1 + + Stack (or queue) operations: + list_append_pop 144.2 93.4 112.7 75.4 74.2 50.8 + deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.5 + deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.8 + + Timing loop: + loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3 + + (Measured from the macOS 64-bit builds found at python.org) From webhook-mailer at python.org Mon Nov 4 09:56:02 2019 From: webhook-mailer at python.org (Christian Heimes) Date: Mon, 04 Nov 2019 14:56:02 -0000 Subject: [Python-checkins] bpo-38684: haslib: fix build when Blake2 not enabled in OpenSSL (#17043) Message-ID: https://github.com/python/cpython/commit/6552563b3d5061816720a5a6c7d4ffd6ba35b98b commit: 6552563b3d5061816720a5a6c7d4ffd6ba35b98b branch: master author: Alexandru Ardelean committer: Christian Heimes date: 2019-11-04T15:55:56+01:00 summary: bpo-38684: haslib: fix build when Blake2 not enabled in OpenSSL (#17043) files: A Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst M Modules/_hashopenssl.c diff --git a/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst b/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst new file mode 100644 index 0000000000000..c715ff9704127 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst @@ -0,0 +1 @@ +Fix _hashlib build when Blake2 is disabled, but OpenSSL supports it. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index b147dbe8b3c55..360e444e7f4ae 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -42,7 +42,7 @@ #define PY_OPENSSL_HAS_SHAKE 1 #endif -#ifdef NID_blake2b512 +#if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) #define PY_OPENSSL_HAS_BLAKE2 1 #endif From webhook-mailer at python.org Mon Nov 4 13:48:38 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 04 Nov 2019 18:48:38 -0000 Subject: [Python-checkins] bpo-38644: Add Py_EnterRecursiveCall() to the limited API (GH-17046) Message-ID: https://github.com/python/cpython/commit/f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 commit: f4b1e3d7c64985f5d5b00f6cc9a1c146bbbfd613 branch: master author: Victor Stinner committer: GitHub date: 2019-11-04T19:48:34+01:00 summary: bpo-38644: Add Py_EnterRecursiveCall() to the limited API (GH-17046) Provide Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as regular functions for the limited API. Previously, there were defined as macros, but these macros didn't work with the limited API which cannot access PyThreadState.recursion_depth field. Remove _Py_CheckRecursionLimit from the stable ABI. Add Include/cpython/ceval.h header file. files: A Include/cpython/ceval.h A Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst M Doc/c-api/exceptions.rst M Doc/whatsnew/3.9.rst M Include/ceval.h M Makefile.pre.in M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/ceval.c diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c7ba74cc8d587..a042c6eee0a29 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -715,15 +715,21 @@ recursion depth automatically). case, a :exc:`RecursionError` is set and a nonzero value is returned. Otherwise, zero is returned. - *where* should be a string such as ``" in instance check"`` to be - concatenated to the :exc:`RecursionError` message caused by the recursion + *where* should be a UTF-8 encoded string such as ``" in instance check"`` to + be concatenated to the :exc:`RecursionError` message caused by the recursion depth limit. -.. c:function:: void Py_LeaveRecursiveCall() + .. versionchanged:: 3.9 + This function is now also available in the limited API. + +.. c:function:: void Py_LeaveRecursiveCall(void) Ends a :c:func:`Py_EnterRecursiveCall`. Must be called once for each *successful* invocation of :c:func:`Py_EnterRecursiveCall`. + .. versionchanged:: 3.9 + This function is now also available in the limited API. + Properly implementing :c:member:`~PyTypeObject.tp_repr` for container types requires special recursion handling. In addition to protecting the stack, :c:member:`~PyTypeObject.tp_repr` also needs to track objects to prevent cycles. The diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 7d7c502459a9b..3cac9c5eedbc2 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -197,6 +197,12 @@ Optimizations Build and C API Changes ======================= +* Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` + as regular functions for the limited API. Previously, there were defined as + macros, but these macros didn't work with the limited API which cannot access + ``PyThreadState.recursion_depth`` field. Remove ``_Py_CheckRecursionLimit`` + from the stable ABI. + (Contributed by Victor Stinner in :issue:`38644`.) * Add a new public :c:func:`PyObject_CallNoArgs` function to the C API, which calls a callable Python object without any arguments. It is the most efficient way to call a callable Python object without any argument. diff --git a/Include/ceval.h b/Include/ceval.h index 61db777cc4d5b..8da779ba97b73 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -85,41 +85,8 @@ PyAPI_FUNC(int) Py_MakePendingCalls(void); PyAPI_FUNC(void) Py_SetRecursionLimit(int); PyAPI_FUNC(int) Py_GetRecursionLimit(void); -#define Py_EnterRecursiveCall(where) \ - (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ - _Py_CheckRecursiveCall(where)) -#define Py_LeaveRecursiveCall() \ - do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ - PyThreadState_GET()->overflowed = 0; \ - } while(0) -PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); - -/* Due to the macros in which it's used, _Py_CheckRecursionLimit is in - the stable ABI. It should be removed therefrom when possible. -*/ -PyAPI_DATA(int) _Py_CheckRecursionLimit; - -#ifdef USE_STACKCHECK -/* With USE_STACKCHECK, trigger stack checks in _Py_CheckRecursiveCall() - on every 64th call to Py_EnterRecursiveCall. -*/ -# define _Py_MakeRecCheck(x) \ - (++(x) > _Py_CheckRecursionLimit || \ - ++(PyThreadState_GET()->stackcheck_counter) > 64) -#else -# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) -#endif - -/* Compute the "lower-water mark" for a recursion limit. When - * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, - * the overflowed flag is reset to 0. */ -#define _Py_RecursionLimitLowerWaterMark(limit) \ - (((limit) > 200) \ - ? ((limit) - 50) \ - : (3 * ((limit) >> 2))) - -#define _Py_MakeEndRecCheck(x) \ - (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) +PyAPI_FUNC(int) Py_EnterRecursiveCall(const char *where); +PyAPI_FUNC(void) Py_LeaveRecursiveCall(void); #define Py_ALLOW_RECURSION \ do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ @@ -224,6 +191,12 @@ PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); #define FVS_MASK 0x4 #define FVS_HAVE_SPEC 0x4 +#ifndef Py_LIMITED_API +# define Py_CPYTHON_CEVAL_H +# include "cpython/ceval.h" +# undef Py_CPYTHON_CEVAL_H +#endif + #ifdef __cplusplus } #endif diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h new file mode 100644 index 0000000000000..61bbc4f69d531 --- /dev/null +++ b/Include/cpython/ceval.h @@ -0,0 +1,50 @@ +#ifndef Py_CPYTHON_CEVAL_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(int) _Py_CheckRecursionLimit; + +#ifdef USE_STACKCHECK +/* With USE_STACKCHECK macro defined, trigger stack checks in + _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */ +# define _Py_MakeRecCheck(x) \ + (++(x) > _Py_CheckRecursionLimit || \ + ++(PyThreadState_GET()->stackcheck_counter) > 64) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); + +#define _Py_EnterRecursiveCall_macro(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) + +#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_macro(where) + + +/* Compute the "lower-water mark" for a recursion limit. When + * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, + * the overflowed flag is reset to 0. */ +#define _Py_RecursionLimitLowerWaterMark(limit) \ + (((limit) > 200) \ + ? ((limit) - 50) \ + : (3 * ((limit) >> 2))) + +#define _Py_MakeEndRecCheck(x) \ + (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) + +#define _Py_LeaveRecursiveCall_macro() \ + do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ + PyThreadState_GET()->overflowed = 0; \ + } while(0) + +#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_macro() + +#ifdef __cplusplus +} +#endif diff --git a/Makefile.pre.in b/Makefile.pre.in index 1c0958ec974b2..3c607d08ae745 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1057,6 +1057,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/Python-ast.h \ \ $(srcdir)/Include/cpython/abstract.h \ + $(srcdir)/Include/cpython/ceval.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ $(srcdir)/Include/cpython/import.h \ diff --git a/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst b/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst new file mode 100644 index 0000000000000..b94f505568f41 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst @@ -0,0 +1,5 @@ +Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` +as regular functions for the limited API. Previously, there were defined as +macros, but these macros didn't work with the limited API which cannot access +``PyThreadState.recursion_depth`` field. Remove ``_Py_CheckRecursionLimit`` +from the stable ABI. diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 1c055b6a33430..b72474060a362 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -127,6 +127,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index dbff89fbff62b..80908135550b6 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -84,6 +84,9 @@ Include + + Include + Include diff --git a/Python/ceval.c b/Python/ceval.c index a7d2ea80069a0..881a7dd629bcc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5632,3 +5632,21 @@ maybe_dtrace_line(PyFrameObject *frame, } *instr_prev = frame->f_lasti; } + + +/* Implement Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as functions + for the limited API. */ + +#undef Py_EnterRecursiveCall + +int Py_EnterRecursiveCall(const char *where) +{ + return _Py_EnterRecursiveCall_macro(where); +} + +#undef Py_LeaveRecursiveCall + +void Py_LeaveRecursiveCall(void) +{ + _Py_LeaveRecursiveCall_macro(); +} From webhook-mailer at python.org Mon Nov 4 18:51:27 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 04 Nov 2019 23:51:27 -0000 Subject: [Python-checkins] bpo-38644: Pass tstate to Py_EnterRecursiveCall() (GH-16997) Message-ID: https://github.com/python/cpython/commit/be434dc0380d9f5c7c800de9943cc46d55fd9491 commit: be434dc0380d9f5c7c800de9943cc46d55fd9491 branch: master author: Victor Stinner committer: GitHub date: 2019-11-05T00:51:22+01:00 summary: bpo-38644: Pass tstate to Py_EnterRecursiveCall() (GH-16997) * Add _Py_EnterRecursiveCall() and _Py_LeaveRecursiveCall() which require a tstate argument. * Pass tstate to _Py_MakeRecCheck() and _Py_CheckRecursiveCall(). * Convert Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() macros to static inline functions. _PyThreadState_GET() is the most efficient way to get the tstate, and so using it with _Py_EnterRecursiveCall() and _Py_LeaveRecursiveCall() should be a little bit more efficient than using Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() which use the "slower" PyThreadState_GET(). files: M Include/cpython/ceval.h M Objects/abstract.c M Objects/call.c M Objects/descrobject.c M Objects/methodobject.c M Objects/object.c M Python/ceval.c diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 61bbc4f69d531..1e2c4577a78ff 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -11,20 +11,31 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit; #ifdef USE_STACKCHECK /* With USE_STACKCHECK macro defined, trigger stack checks in _Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */ -# define _Py_MakeRecCheck(x) \ - (++(x) > _Py_CheckRecursionLimit || \ - ++(PyThreadState_GET()->stackcheck_counter) > 64) +static inline int _Py_MakeRecCheck(PyThreadState *tstate) { + return (++tstate->recursion_depth > _Py_CheckRecursionLimit + || ++tstate->stackcheck_counter > 64); +} #else -# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +static inline int _Py_MakeRecCheck(PyThreadState *tstate) { + return (++tstate->recursion_depth > _Py_CheckRecursionLimit); +} #endif -PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); +PyAPI_FUNC(int) _Py_CheckRecursiveCall( + PyThreadState *tstate, + const char *where); + +static inline int _Py_EnterRecursiveCall(PyThreadState *tstate, + const char *where) { + return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); +} -#define _Py_EnterRecursiveCall_macro(where) \ - (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ - _Py_CheckRecursiveCall(where)) +static inline int _Py_EnterRecursiveCall_inline(const char *where) { + PyThreadState *tstate = PyThreadState_GET(); + return _Py_EnterRecursiveCall(tstate, where); +} -#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_macro(where) +#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where) /* Compute the "lower-water mark" for a recursion limit. When @@ -38,12 +49,18 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); #define _Py_MakeEndRecCheck(x) \ (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) -#define _Py_LeaveRecursiveCall_macro() \ - do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ - PyThreadState_GET()->overflowed = 0; \ - } while(0) +static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) { + if (_Py_MakeEndRecCheck(tstate->recursion_depth)) { + tstate->overflowed = 0; + } +} + +static inline void _Py_LeaveRecursiveCall_inline(void) { + PyThreadState *tstate = PyThreadState_GET(); + _Py_LeaveRecursiveCall(tstate); +} -#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_macro() +#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline() #ifdef __cplusplus } diff --git a/Objects/abstract.c b/Objects/abstract.c index 3db56fab2c8db..dc8ba10762de6 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1,6 +1,7 @@ /* Abstract Object Interface (many thanks to Jim Fulton) */ #include "Python.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include #include "structmember.h" /* we need the offsetof() macro from there */ @@ -2459,8 +2460,8 @@ recursive_isinstance(PyObject *inst, PyObject *cls) return retval; } -int -PyObject_IsInstance(PyObject *inst, PyObject *cls) +static int +object_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls) { _Py_IDENTIFIER(__instancecheck__); PyObject *checker; @@ -2475,34 +2476,31 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) } if (PyTuple_Check(cls)) { - Py_ssize_t i; - Py_ssize_t n; - int r = 0; - - if (Py_EnterRecursiveCall(" in __instancecheck__")) + if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { return -1; - n = PyTuple_GET_SIZE(cls); - for (i = 0; i < n; ++i) { + } + Py_ssize_t n = PyTuple_GET_SIZE(cls); + int r = 0; + for (Py_ssize_t i = 0; i < n; ++i) { PyObject *item = PyTuple_GET_ITEM(cls, i); - r = PyObject_IsInstance(inst, item); + r = object_isinstance(tstate, inst, item); if (r != 0) /* either found it, or got an error */ break; } - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return r; } checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); if (checker != NULL) { - PyObject *res; int ok = -1; - if (Py_EnterRecursiveCall(" in __instancecheck__")) { + if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) { Py_DECREF(checker); return ok; } - res = _PyObject_CallOneArg(checker, inst); - Py_LeaveRecursiveCall(); + PyObject *res = _PyObject_CallOneArg(checker, inst); + _Py_LeaveRecursiveCall(tstate); Py_DECREF(checker); if (res != NULL) { ok = PyObject_IsTrue(res); @@ -2510,12 +2508,23 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) } return ok; } - else if (PyErr_Occurred()) + else if (_PyErr_Occurred(tstate)) { return -1; + } + /* Probably never reached anymore. */ return recursive_isinstance(inst, cls); } + +int +PyObject_IsInstance(PyObject *inst, PyObject *cls) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return object_isinstance(tstate, inst, cls); +} + + static int recursive_issubclass(PyObject *derived, PyObject *cls) { @@ -2534,8 +2543,8 @@ recursive_issubclass(PyObject *derived, PyObject *cls) return abstract_issubclass(derived, cls); } -int -PyObject_IsSubclass(PyObject *derived, PyObject *cls) +static int +object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls) { _Py_IDENTIFIER(__subclasscheck__); PyObject *checker; @@ -2549,34 +2558,32 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) } if (PyTuple_Check(cls)) { - Py_ssize_t i; - Py_ssize_t n; - int r = 0; - if (Py_EnterRecursiveCall(" in __subclasscheck__")) + if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) { return -1; - n = PyTuple_GET_SIZE(cls); - for (i = 0; i < n; ++i) { + } + Py_ssize_t n = PyTuple_GET_SIZE(cls); + int r = 0; + for (Py_ssize_t i = 0; i < n; ++i) { PyObject *item = PyTuple_GET_ITEM(cls, i); - r = PyObject_IsSubclass(derived, item); + r = object_issubclass(tstate, derived, item); if (r != 0) /* either found it, or got an error */ break; } - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return r; } checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__); if (checker != NULL) { - PyObject *res; int ok = -1; - if (Py_EnterRecursiveCall(" in __subclasscheck__")) { + if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) { Py_DECREF(checker); return ok; } - res = _PyObject_CallOneArg(checker, derived); - Py_LeaveRecursiveCall(); + PyObject *res = _PyObject_CallOneArg(checker, derived); + _Py_LeaveRecursiveCall(tstate); Py_DECREF(checker); if (res != NULL) { ok = PyObject_IsTrue(res); @@ -2584,12 +2591,23 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) } return ok; } - else if (PyErr_Occurred()) + else if (_PyErr_Occurred(tstate)) { return -1; + } + /* Probably never reached anymore. */ return recursive_issubclass(derived, cls); } + +int +PyObject_IsSubclass(PyObject *derived, PyObject *cls) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return object_issubclass(tstate, derived, cls); +} + + int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls) { diff --git a/Objects/call.c b/Objects/call.c index a715bcbee4add..b7588b302fb7d 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" #include "frameobject.h" @@ -126,12 +127,15 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, PyObject * _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { + PyThreadState *tstate = _PyThreadState_GET(); + /* Slow path: build a temporary tuple for positional arguments and a * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; if (call == NULL) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - Py_TYPE(callable)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not callable", + Py_TYPE(callable)->tp_name); return NULL; } @@ -162,10 +166,10 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs } PyObject *result = NULL; - if (Py_EnterRecursiveCall(" while calling a Python object") == 0) + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0) { result = call(callable, argstuple, kwdict); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); } Py_DECREF(argstuple); @@ -220,13 +224,14 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) PyObject * PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) { + PyThreadState *tstate = _PyThreadState_GET(); ternaryfunc call; PyObject *result; /* PyObject_Call() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); @@ -236,17 +241,19 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) else { call = callable->ob_type->tp_call; if (call == NULL) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - callable->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not callable", + callable->ob_type->tp_name); return NULL; } - if (Py_EnterRecursiveCall(" while calling a Python object")) + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { return NULL; + } result = (*call)(callable, args, kwargs); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return _Py_CheckFunctionResult(callable, result, NULL); } @@ -266,30 +273,27 @@ static PyObject* _Py_HOT_FUNCTION function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs, PyObject *globals) { - PyFrameObject *f; + assert(globals != NULL); + PyThreadState *tstate = _PyThreadState_GET(); - PyObject **fastlocals; - Py_ssize_t i; - PyObject *result; + assert(tstate != NULL); - assert(globals != NULL); /* XXX Perhaps we should create a specialized _PyFrame_New_NoTrack() that doesn't take locals, but does take builtins without sanity checking them. */ - assert(tstate != NULL); - f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); if (f == NULL) { return NULL; } - fastlocals = f->f_localsplus; + PyObject **fastlocals = f->f_localsplus; - for (i = 0; i < nargs; i++) { + for (Py_ssize_t i = 0; i < nargs; i++) { Py_INCREF(*args); fastlocals[i] = *args++; } - result = PyEval_EvalFrameEx(f,0); + PyObject *result = PyEval_EvalFrameEx(f, 0); if (Py_REFCNT(f) > 1) { Py_DECREF(f); diff --git a/Objects/descrobject.c b/Objects/descrobject.c index c50fe00ce80bd..dbab4cd4da2c6 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -271,9 +271,9 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj } static inline funcptr -method_enter_call(PyObject *func) +method_enter_call(PyThreadState *tstate, PyObject *func) { - if (Py_EnterRecursiveCall(" while calling a Python object")) { + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { return NULL; } return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth; @@ -284,6 +284,7 @@ static PyObject * method_vectorcall_VARARGS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, kwnames)) { return NULL; @@ -292,14 +293,14 @@ method_vectorcall_VARARGS( if (argstuple == NULL) { return NULL; } - PyCFunction meth = (PyCFunction)method_enter_call(func); + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); if (meth == NULL) { Py_DECREF(argstuple); return NULL; } PyObject *result = meth(args[0], argstuple); Py_DECREF(argstuple); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -307,6 +308,7 @@ static PyObject * method_vectorcall_VARARGS_KEYWORDS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, NULL)) { return NULL; @@ -325,12 +327,12 @@ method_vectorcall_VARARGS_KEYWORDS( } } PyCFunctionWithKeywords meth = (PyCFunctionWithKeywords) - method_enter_call(func); + method_enter_call(tstate, func); if (meth == NULL) { goto exit; } result = meth(args[0], argstuple, kwdict); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); exit: Py_DECREF(argstuple); Py_XDECREF(kwdict); @@ -341,17 +343,18 @@ static PyObject * method_vectorcall_FASTCALL( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, kwnames)) { return NULL; } _PyCFunctionFast meth = (_PyCFunctionFast) - method_enter_call(func); + method_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(args[0], args+1, nargs-1); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -359,17 +362,18 @@ static PyObject * method_vectorcall_FASTCALL_KEYWORDS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, NULL)) { return NULL; } _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) - method_enter_call(func); + method_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(args[0], args+1, nargs-1, kwnames); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -377,6 +381,7 @@ static PyObject * method_vectorcall_NOARGS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, kwnames)) { return NULL; @@ -386,12 +391,12 @@ method_vectorcall_NOARGS( "%.200s() takes no arguments (%zd given)", get_name(func), nargs-1); return NULL; } - PyCFunction meth = (PyCFunction)method_enter_call(func); + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(args[0], NULL); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -399,6 +404,7 @@ static PyObject * method_vectorcall_O( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (method_check_args(func, args, nargs, kwnames)) { return NULL; @@ -409,12 +415,12 @@ method_vectorcall_O( get_name(func), nargs-1); return NULL; } - PyCFunction meth = (PyCFunction)method_enter_call(func); + PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(args[0], args[1]); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index a5f0c5d3465de..3ce15604b90f1 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" @@ -344,22 +345,22 @@ get_name(PyObject *func) typedef void (*funcptr)(void); static inline int -cfunction_check_kwargs(PyObject *func, PyObject *kwnames) +cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); assert(PyCFunction_Check(func)); if (kwnames && PyTuple_GET_SIZE(kwnames)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", get_name(func)); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes no keyword arguments", get_name(func)); return -1; } return 0; } static inline funcptr -cfunction_enter_call(PyObject *func) +cfunction_enter_call(PyThreadState *tstate, PyObject *func) { - if (Py_EnterRecursiveCall(" while calling a Python object")) { + if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) { return NULL; } return (funcptr)PyCFunction_GET_FUNCTION(func); @@ -370,17 +371,18 @@ static PyObject * cfunction_vectorcall_FASTCALL( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); _PyCFunctionFast meth = (_PyCFunctionFast) - cfunction_enter_call(func); + cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -388,14 +390,15 @@ static PyObject * cfunction_vectorcall_FASTCALL_KEYWORDS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); _PyCFunctionFastWithKeywords meth = (_PyCFunctionFastWithKeywords) - cfunction_enter_call(func); + cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -403,21 +406,23 @@ static PyObject * cfunction_vectorcall_NOARGS( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 0) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%zd given)", get_name(func), nargs); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", + get_name(func), nargs); return NULL; } - PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } @@ -425,22 +430,23 @@ static PyObject * cfunction_vectorcall_O( PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) { - if (cfunction_check_kwargs(func, kwnames)) { + PyThreadState *tstate = _PyThreadState_GET(); + if (cfunction_check_kwargs(tstate, func, kwnames)) { return NULL; } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 1) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%zd given)", - get_name(func), nargs); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + get_name(func), nargs); return NULL; } - PyCFunction meth = (PyCFunction)cfunction_enter_call(func); + PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); if (meth == NULL) { return NULL; } PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); return result; } diff --git a/Objects/object.c b/Objects/object.c index 2c8e823f05ee9..9536d467f5f2a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2,10 +2,11 @@ /* Generic object operations; and implementation of None */ #include "Python.h" +#include "pycore_context.h" #include "pycore_initconfig.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" -#include "pycore_context.h" #include "frameobject.h" #include "interpreteridobject.h" @@ -525,31 +526,37 @@ PyObject_Repr(PyObject *v) return PyUnicode_FromFormat("<%s object at %p>", v->ob_type->tp_name, v); + PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG /* PyObject_Repr() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif /* It is possible for a type to have a tp_repr representation that loops infinitely. */ - if (Py_EnterRecursiveCall(" while getting the repr of an object")) + if (_Py_EnterRecursiveCall(tstate, + " while getting the repr of an object")) { return NULL; + } res = (*v->ob_type->tp_repr)(v); - Py_LeaveRecursiveCall(); - if (res == NULL) + _Py_LeaveRecursiveCall(tstate); + + if (res == NULL) { return NULL; + } if (!PyUnicode_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__repr__ returned non-string (type %.200s)", - res->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "__repr__ returned non-string (type %.200s)", + res->ob_type->tp_name); Py_DECREF(res); return NULL; } #ifndef Py_DEBUG - if (PyUnicode_READY(res) < 0) + if (PyUnicode_READY(res) < 0) { return NULL; + } #endif return res; } @@ -579,31 +586,36 @@ PyObject_Str(PyObject *v) if (Py_TYPE(v)->tp_str == NULL) return PyObject_Repr(v); + PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG /* PyObject_Str() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif /* It is possible for a type to have a tp_str representation that loops infinitely. */ - if (Py_EnterRecursiveCall(" while getting the str of an object")) + if (_Py_EnterRecursiveCall(tstate, " while getting the str of an object")) { return NULL; + } res = (*Py_TYPE(v)->tp_str)(v); - Py_LeaveRecursiveCall(); - if (res == NULL) + _Py_LeaveRecursiveCall(tstate); + + if (res == NULL) { return NULL; + } if (!PyUnicode_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__str__ returned non-string (type %.200s)", - Py_TYPE(res)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "__str__ returned non-string (type %.200s)", + Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } #ifndef Py_DEBUG - if (PyUnicode_READY(res) < 0) + if (PyUnicode_READY(res) < 0) { return NULL; + } #endif assert(_PyUnicode_CheckConsistency(res, 1)); return res; @@ -707,7 +719,7 @@ static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="}; /* Perform a rich comparison, raising TypeError when the requested comparison operator is not supported. */ static PyObject * -do_richcompare(PyObject *v, PyObject *w, int op) +do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) { richcmpfunc f; PyObject *res; @@ -744,11 +756,11 @@ do_richcompare(PyObject *v, PyObject *w, int op) res = (v != w) ? Py_True : Py_False; break; default: - PyErr_Format(PyExc_TypeError, - "'%s' not supported between instances of '%.100s' and '%.100s'", - opstrings[op], - v->ob_type->tp_name, - w->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'%s' not supported between instances of '%.100s' and '%.100s'", + opstrings[op], + v->ob_type->tp_name, + w->ob_type->tp_name); return NULL; } Py_INCREF(res); @@ -761,18 +773,20 @@ do_richcompare(PyObject *v, PyObject *w, int op) PyObject * PyObject_RichCompare(PyObject *v, PyObject *w, int op) { - PyObject *res; + PyThreadState *tstate = _PyThreadState_GET(); assert(Py_LT <= op && op <= Py_GE); if (v == NULL || w == NULL) { - if (!PyErr_Occurred()) + if (!_PyErr_Occurred(tstate)) { PyErr_BadInternalCall(); + } return NULL; } - if (Py_EnterRecursiveCall(" in comparison")) + if (_Py_EnterRecursiveCall(tstate, " in comparison")) { return NULL; - res = do_richcompare(v, w, op); - Py_LeaveRecursiveCall(); + } + PyObject *res = do_richcompare(tstate, v, w, op); + _Py_LeaveRecursiveCall(tstate); return res; } diff --git a/Python/ceval.c b/Python/ceval.c index 881a7dd629bcc..a01fa35dca2d0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -659,16 +659,15 @@ Py_SetRecursionLimit(int new_limit) _Py_CheckRecursionLimit = ceval->recursion_limit; } -/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() +/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches _Py_CheckRecursionLimit. If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit to guarantee that _Py_CheckRecursiveCall() is regularly called. Without USE_STACKCHECK, there is no need for this. */ int -_Py_CheckRecursiveCall(const char *where) +_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); int recursion_limit = runtime->ceval.recursion_limit; #ifdef USE_STACKCHECK @@ -1073,8 +1072,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* Start of code */ /* push frame */ - if (Py_EnterRecursiveCall("")) + if (_Py_EnterRecursiveCall(tstate, "")) { return NULL; + } tstate->frame = f; @@ -3810,7 +3810,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) exit_eval_frame: if (PyDTrace_FUNCTION_RETURN_ENABLED()) dtrace_function_return(f); - Py_LeaveRecursiveCall(); + _Py_LeaveRecursiveCall(tstate); f->f_executing = 0; tstate->frame = f->f_back; @@ -5641,12 +5641,12 @@ maybe_dtrace_line(PyFrameObject *frame, int Py_EnterRecursiveCall(const char *where) { - return _Py_EnterRecursiveCall_macro(where); + return _Py_EnterRecursiveCall_inline(where); } #undef Py_LeaveRecursiveCall void Py_LeaveRecursiveCall(void) { - _Py_LeaveRecursiveCall_macro(); + _Py_LeaveRecursiveCall_inline(); } From webhook-mailer at python.org Mon Nov 4 19:22:16 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 05 Nov 2019 00:22:16 -0000 Subject: [Python-checkins] bpo-38644: Pass tstate to _Py_CheckFunctionResult() (GH-17050) Message-ID: https://github.com/python/cpython/commit/17269090940aa20f6079a6b9f27ae319f8cdae14 commit: 17269090940aa20f6079a6b9f27ae319f8cdae14 branch: master author: Victor Stinner committer: GitHub date: 2019-11-05T01:22:12+01:00 summary: bpo-38644: Pass tstate to _Py_CheckFunctionResult() (GH-17050) * Add tstate parameter to _Py_CheckFunctionResult() * Add _PyErr_FormatFromCauseTstate() * Replace PyErr_XXX(...) with _PyErr_XXX(state, ...) files: M Include/cpython/abstract.h M Include/internal/pycore_pyerrors.h M Objects/call.c M Objects/methodobject.c M Objects/typeobject.c M Python/ceval.c M Python/errors.c diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 04e4a9e7bd277..be37e1971a814 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -37,9 +37,11 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict( 40 bytes on the stack. */ #define _PY_FASTCALL_SMALL_STACK 5 -PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, - PyObject *result, - const char *where); +PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( + PyThreadState *tstate, + PyObject *callable, + PyObject *result, + const char *where); /* === Vectorcall protocol (PEP 590) ============================= */ @@ -98,13 +100,15 @@ _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, { assert(kwnames == NULL || PyTuple_Check(kwnames)); assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); + + PyThreadState *tstate = PyThreadState_GET(); vectorcallfunc func = _PyVectorcall_Function(callable); if (func == NULL) { Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); return _PyObject_MakeTpCall(callable, args, nargs, kwnames); } PyObject *res = func(callable, args, nargsf, kwnames); - return _Py_CheckFunctionResult(callable, res, NULL); + return _Py_CheckFunctionResult(tstate, callable, res, NULL); } /* Same as _PyObject_Vectorcall except that keyword arguments are passed as diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index 2efbf4a62f817..edbfdfa597e1f 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -58,6 +58,12 @@ PyAPI_FUNC(void) _PyErr_NormalizeException( PyObject **val, PyObject **tb); +PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate( + PyThreadState *tstate, + PyObject *exception, + const char *format, + ...); + #ifdef __cplusplus } #endif diff --git a/Objects/call.c b/Objects/call.c index b7588b302fb7d..0d5c41295c29c 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -7,8 +7,9 @@ static PyObject *const * -_PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, - PyObject **p_kwnames); +_PyStack_UnpackDict(PyThreadState *tstate, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject **p_kwnames); static void _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, @@ -26,22 +27,23 @@ null_error(void) PyObject* -_Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) +_Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, + PyObject *result, const char *where) { - int err_occurred = (PyErr_Occurred() != NULL); + int err_occurred = (_PyErr_Occurred(tstate) != NULL); assert((callable != NULL) ^ (where != NULL)); if (result == NULL) { if (!err_occurred) { if (callable) - PyErr_Format(PyExc_SystemError, - "%R returned NULL without setting an error", - callable); + _PyErr_Format(tstate, PyExc_SystemError, + "%R returned NULL without setting an error", + callable); else - PyErr_Format(PyExc_SystemError, - "%s returned NULL without setting an error", - where); + _PyErr_Format(tstate, PyExc_SystemError, + "%s returned NULL without setting an error", + where); #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode */ Py_FatalError("a function returned NULL without setting an error"); @@ -54,14 +56,14 @@ _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) Py_DECREF(result); if (callable) { - _PyErr_FormatFromCause(PyExc_SystemError, - "%R returned a result with an error set", - callable); + _PyErr_FormatFromCauseTstate( + tstate, PyExc_SystemError, + "%R returned a result with an error set", callable); } else { - _PyErr_FormatFromCause(PyExc_SystemError, - "%s returned a result with an error set", - where); + _PyErr_FormatFromCauseTstate( + tstate, PyExc_SystemError, + "%s returned a result with an error set", where); } #ifdef Py_DEBUG /* Ensure that the bug is caught in debug mode */ @@ -88,11 +90,13 @@ PyObject * _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwargs) { + assert(callable != NULL); + + PyThreadState *tstate = _PyThreadState_GET(); /* _PyObject_FastCallDict() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); - assert(callable != NULL); + assert(!_PyErr_Occurred(tstate)); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); @@ -112,7 +116,9 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, else { PyObject *kwnames; PyObject *const *newargs; - newargs = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames); + newargs = _PyStack_UnpackDict(tstate, + args, nargs, + kwargs, &kwnames); if (newargs == NULL) { return NULL; } @@ -120,7 +126,7 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); _PyStack_UnpackDict_Free(newargs, nargs, kwnames); } - return _Py_CheckFunctionResult(callable, res, NULL); + return _Py_CheckFunctionResult(tstate, callable, res, NULL); } @@ -177,7 +183,7 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs Py_DECREF(kwdict); } - result = _Py_CheckFunctionResult(callable, result, NULL); + result = _Py_CheckFunctionResult(tstate, callable, result, NULL); return result; } @@ -185,18 +191,22 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) { + PyThreadState *tstate = _PyThreadState_GET(); + /* get vectorcallfunc as in _PyVectorcall_Function, but without * the _Py_TPFLAGS_HAVE_VECTORCALL check */ Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; if (offset <= 0) { - PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", - Py_TYPE(callable)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); return NULL; } vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); if (func == NULL) { - PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", - Py_TYPE(callable)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); return NULL; } @@ -210,14 +220,16 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) /* Convert arguments & call */ PyObject *const *args; PyObject *kwnames; - args = _PyStack_UnpackDict(_PyTuple_ITEMS(tuple), nargs, kwargs, &kwnames); + args = _PyStack_UnpackDict(tstate, + _PyTuple_ITEMS(tuple), nargs, + kwargs, &kwnames); if (args == NULL) { return NULL; } PyObject *result = func(callable, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); _PyStack_UnpackDict_Free(args, nargs, kwnames); - return _Py_CheckFunctionResult(callable, result, NULL); + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } @@ -255,7 +267,7 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) _Py_LeaveRecursiveCall(tstate); - return _Py_CheckFunctionResult(callable, result, NULL); + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } } @@ -898,8 +910,9 @@ _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ static PyObject *const * -_PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, - PyObject **p_kwnames) +_PyStack_UnpackDict(PyThreadState *tstate, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject **p_kwnames) { assert(nargs >= 0); assert(kwargs != NULL); @@ -911,14 +924,14 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, * non-negative signed integers, so their difference fits in the type. */ Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1; if (nargs > maxnargs - nkwargs) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */ PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0])); if (stack == NULL) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } @@ -958,8 +971,8 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, * because it simplifies the deallocation in the failing case. * It happens to also make the loop above slightly more efficient. */ if (!keys_are_strings) { - PyErr_SetString(PyExc_TypeError, - "keywords must be strings"); + _PyErr_SetString(tstate, PyExc_TypeError, + "keywords must be strings"); _PyStack_UnpackDict_Free(stack, nargs, kwnames); return NULL; } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 3ce15604b90f1..c780904d7f9aa 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -454,9 +454,11 @@ cfunction_vectorcall_O( static PyObject * cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) { - assert(!PyErr_Occurred()); assert(kwargs == NULL || PyDict_Check(kwargs)); + PyThreadState *tstate = _PyThreadState_GET(); + assert(!_PyErr_Occurred(tstate)); + int flags = PyCFunction_GET_FLAGS(func); if (!(flags & METH_VARARGS)) { /* If this is not a METH_VARARGS function, delegate to vectorcall */ @@ -474,11 +476,12 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) } else { if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - ((PyCFunctionObject*)func)->m_ml->ml_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s() takes no keyword arguments", + ((PyCFunctionObject*)func)->m_ml->ml_name); return NULL; } result = meth(self, args); } - return _Py_CheckFunctionResult(func, result, NULL); + return _Py_CheckFunctionResult(tstate, func, result, NULL); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 890246e14a695..0e1cb7b7aeb36 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "frameobject.h" #include "structmember.h" @@ -952,12 +953,12 @@ type_repr(PyTypeObject *type) static PyObject * type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *obj; + PyThreadState *tstate = _PyThreadState_GET(); if (type->tp_new == NULL) { - PyErr_Format(PyExc_TypeError, - "cannot create '%.100s' instances", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "cannot create '%.100s' instances", + type->tp_name); return NULL; } @@ -965,11 +966,11 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) /* type_call() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif - obj = type->tp_new(type, args, kwds); - obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL); + PyObject *obj = type->tp_new(type, args, kwds); + obj = _Py_CheckFunctionResult(tstate, (PyObject*)type, obj, NULL); if (obj == NULL) return NULL; @@ -990,12 +991,12 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) if (type->tp_init != NULL) { int res = type->tp_init(obj, args, kwds); if (res < 0) { - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(tstate)); Py_DECREF(obj); obj = NULL; } else { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); } } return obj; diff --git a/Python/ceval.c b/Python/ceval.c index a01fa35dca2d0..9019c785080a3 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3814,7 +3814,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) f->f_executing = 0; tstate->frame = f->f_back; - return _Py_CheckFunctionResult(NULL, retval, "PyEval_EvalFrameEx"); + return _Py_CheckFunctionResult(tstate, NULL, retval, "PyEval_EvalFrameEx"); } static void diff --git a/Python/errors.c b/Python/errors.c index b935341636f78..9658afeb9f773 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -520,6 +520,21 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, return NULL; } +PyObject * +_PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatVFromCause(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + PyObject * _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) { From webhook-mailer at python.org Mon Nov 4 23:32:14 2019 From: webhook-mailer at python.org (Zachary Ware) Date: Tue, 05 Nov 2019 04:32:14 -0000 Subject: [Python-checkins] Fix a typo in wave module docstring (GH-17009) Message-ID: https://github.com/python/cpython/commit/25fa3ecb98f2c038a422b19c53641fa8e3ef8e52 commit: 25fa3ecb98f2c038a422b19c53641fa8e3ef8e52 branch: master author: Michael Haas committer: Zachary Ware date: 2019-11-04T22:32:10-06:00 summary: Fix a typo in wave module docstring (GH-17009) s/pathing/patching/ files: M Lib/wave.py diff --git a/Lib/wave.py b/Lib/wave.py index 100420db9e162..b7071198e6b84 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -53,7 +53,7 @@ -- set all parameters at once tell() -- return current position in output file writeframesraw(data) - -- write audio frames without pathing up the + -- write audio frames without patching up the file header writeframes(data) -- write audio frames and patch up the file header From webhook-mailer at python.org Mon Nov 4 23:50:05 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 04:50:05 -0000 Subject: [Python-checkins] Fix a typo in wave module docstring (GH-17009) Message-ID: https://github.com/python/cpython/commit/1f9148bdb41ca222d7bbdec6a17f74bb847a29f4 commit: 1f9148bdb41ca222d7bbdec6a17f74bb847a29f4 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-04T20:50:01-08:00 summary: Fix a typo in wave module docstring (GH-17009) s/pathing/patching/ (cherry picked from commit 25fa3ecb98f2c038a422b19c53641fa8e3ef8e52) Co-authored-by: Michael Haas files: M Lib/wave.py diff --git a/Lib/wave.py b/Lib/wave.py index f155879a9a76a..823f091deaaad 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -53,7 +53,7 @@ -- set all parameters at once tell() -- return current position in output file writeframesraw(data) - -- write audio frames without pathing up the + -- write audio frames without patching up the file header writeframes(data) -- write audio frames and patch up the file header From webhook-mailer at python.org Tue Nov 5 00:09:55 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 05:09:55 -0000 Subject: [Python-checkins] Fix a typo in wave module docstring (GH-17009) Message-ID: https://github.com/python/cpython/commit/e8bad630349521eb117d486ead2f8602dd172fcb commit: e8bad630349521eb117d486ead2f8602dd172fcb branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-04T21:09:48-08:00 summary: Fix a typo in wave module docstring (GH-17009) s/pathing/patching/ (cherry picked from commit 25fa3ecb98f2c038a422b19c53641fa8e3ef8e52) Co-authored-by: Michael Haas files: M Lib/wave.py diff --git a/Lib/wave.py b/Lib/wave.py index f155879a9a76a..823f091deaaad 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -53,7 +53,7 @@ -- set all parameters at once tell() -- return current position in output file writeframesraw(data) - -- write audio frames without pathing up the + -- write audio frames without patching up the file header writeframes(data) -- write audio frames and patch up the file header From webhook-mailer at python.org Tue Nov 5 00:34:18 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 05 Nov 2019 05:34:18 -0000 Subject: [Python-checkins] =?utf-8?q?closes_bpo-37633=3A_Re=C3=ABxport_so?= =?utf-8?q?me_function_compatibility_wrappers_for_macros_in_=60=60pythonru?= =?utf-8?b?bi5oYGAuIChHSC0xNzA1Nik=?= Message-ID: https://github.com/python/cpython/commit/62161ce989d7d4fe2b0e6899a54da20feeddc798 commit: 62161ce989d7d4fe2b0e6899a54da20feeddc798 branch: master author: Benjamin Peterson committer: GitHub date: 2019-11-04T21:34:14-08:00 summary: closes bpo-37633: Re?xport some function compatibility wrappers for macros in ``pythonrun.h``. (GH-17056) files: A Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst M Python/pythonrun.c diff --git a/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst b/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst new file mode 100644 index 0000000000000..fdf6abbf1c649 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst @@ -0,0 +1 @@ +Re?xport some function compatibility wrappers for macros in ``pythonrun.h``. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 702505893fb99..77a95ceb94bf0 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1648,56 +1648,56 @@ PyOS_CheckStack(void) /* Deprecated C API functions still provided for binary compatibility */ #undef PyParser_SimpleParseFile -node * +PyAPI_FUNC(node *) PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) { return PyParser_SimpleParseFileFlags(fp, filename, start, 0); } #undef PyParser_SimpleParseString -node * +PyAPI_FUNC(node *) PyParser_SimpleParseString(const char *str, int start) { return PyParser_SimpleParseStringFlags(str, start, 0); } #undef PyRun_AnyFile -int +PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name) { return PyRun_AnyFileExFlags(fp, name, 0, NULL); } #undef PyRun_AnyFileEx -int +PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit) { return PyRun_AnyFileExFlags(fp, name, closeit, NULL); } #undef PyRun_AnyFileFlags -int +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags) { return PyRun_AnyFileExFlags(fp, name, 0, flags); } #undef PyRun_File -PyObject * +PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l) { return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); } #undef PyRun_FileEx -PyObject * +PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c) { return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); } #undef PyRun_FileFlags -PyObject * +PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags) { @@ -1705,14 +1705,14 @@ PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, } #undef PyRun_SimpleFile -int +PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p) { return PyRun_SimpleFileExFlags(f, p, 0, NULL); } #undef PyRun_SimpleFileEx -int +PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c) { return PyRun_SimpleFileExFlags(f, p, c, NULL); @@ -1720,28 +1720,28 @@ PyRun_SimpleFileEx(FILE *f, const char *p, int c) #undef PyRun_String -PyObject * +PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l) { return PyRun_StringFlags(str, s, g, l, NULL); } #undef PyRun_SimpleString -int +PyAPI_FUNC(int) PyRun_SimpleString(const char *s) { return PyRun_SimpleStringFlags(s, NULL); } #undef Py_CompileString -PyObject * +PyAPI_FUNC(PyObject *) Py_CompileString(const char *str, const char *p, int s) { return Py_CompileStringExFlags(str, p, s, NULL, -1); } #undef Py_CompileStringFlags -PyObject * +PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *str, const char *p, int s, PyCompilerFlags *flags) { @@ -1749,14 +1749,14 @@ Py_CompileStringFlags(const char *str, const char *p, int s, } #undef PyRun_InteractiveOne -int +PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p) { return PyRun_InteractiveOneFlags(f, p, NULL); } #undef PyRun_InteractiveLoop -int +PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p) { return PyRun_InteractiveLoopFlags(f, p, NULL); From webhook-mailer at python.org Tue Nov 5 00:53:03 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 05:53:03 -0000 Subject: [Python-checkins] =?utf-8?q?closes_bpo-37633=3A_Re=C3=ABxport_so?= =?utf-8?q?me_function_compatibility_wrappers_for_macros_in_=60=60pythonru?= =?utf-8?b?bi5oYGAuIChHSC0xNzA1Nik=?= Message-ID: https://github.com/python/cpython/commit/4c22e1665c4d8e8fa31bd7aa7b403480d9be5ce2 commit: 4c22e1665c4d8e8fa31bd7aa7b403480d9be5ce2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-04T21:52:59-08:00 summary: closes bpo-37633: Re?xport some function compatibility wrappers for macros in ``pythonrun.h``. (GH-17056) (cherry picked from commit 62161ce989d7d4fe2b0e6899a54da20feeddc798) Co-authored-by: Benjamin Peterson files: A Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst M Python/pythonrun.c diff --git a/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst b/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst new file mode 100644 index 0000000000000..fdf6abbf1c649 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst @@ -0,0 +1 @@ +Re?xport some function compatibility wrappers for macros in ``pythonrun.h``. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f1d946a0b0f83..c9afa8f8baaf8 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1648,56 +1648,56 @@ PyOS_CheckStack(void) /* Deprecated C API functions still provided for binary compatibility */ #undef PyParser_SimpleParseFile -node * +PyAPI_FUNC(node *) PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) { return PyParser_SimpleParseFileFlags(fp, filename, start, 0); } #undef PyParser_SimpleParseString -node * +PyAPI_FUNC(node *) PyParser_SimpleParseString(const char *str, int start) { return PyParser_SimpleParseStringFlags(str, start, 0); } #undef PyRun_AnyFile -int +PyAPI_FUNC(int) PyRun_AnyFile(FILE *fp, const char *name) { return PyRun_AnyFileExFlags(fp, name, 0, NULL); } #undef PyRun_AnyFileEx -int +PyAPI_FUNC(int) PyRun_AnyFileEx(FILE *fp, const char *name, int closeit) { return PyRun_AnyFileExFlags(fp, name, closeit, NULL); } #undef PyRun_AnyFileFlags -int +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags) { return PyRun_AnyFileExFlags(fp, name, 0, flags); } #undef PyRun_File -PyObject * +PyAPI_FUNC(PyObject *) PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l) { return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL); } #undef PyRun_FileEx -PyObject * +PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c) { return PyRun_FileExFlags(fp, p, s, g, l, c, NULL); } #undef PyRun_FileFlags -PyObject * +PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags) { @@ -1705,14 +1705,14 @@ PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, } #undef PyRun_SimpleFile -int +PyAPI_FUNC(int) PyRun_SimpleFile(FILE *f, const char *p) { return PyRun_SimpleFileExFlags(f, p, 0, NULL); } #undef PyRun_SimpleFileEx -int +PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *f, const char *p, int c) { return PyRun_SimpleFileExFlags(f, p, c, NULL); @@ -1720,28 +1720,28 @@ PyRun_SimpleFileEx(FILE *f, const char *p, int c) #undef PyRun_String -PyObject * +PyAPI_FUNC(PyObject *) PyRun_String(const char *str, int s, PyObject *g, PyObject *l) { return PyRun_StringFlags(str, s, g, l, NULL); } #undef PyRun_SimpleString -int +PyAPI_FUNC(int) PyRun_SimpleString(const char *s) { return PyRun_SimpleStringFlags(s, NULL); } #undef Py_CompileString -PyObject * +PyAPI_FUNC(PyObject *) Py_CompileString(const char *str, const char *p, int s) { return Py_CompileStringExFlags(str, p, s, NULL, -1); } #undef Py_CompileStringFlags -PyObject * +PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *str, const char *p, int s, PyCompilerFlags *flags) { @@ -1749,14 +1749,14 @@ Py_CompileStringFlags(const char *str, const char *p, int s, } #undef PyRun_InteractiveOne -int +PyAPI_FUNC(int) PyRun_InteractiveOne(FILE *f, const char *p) { return PyRun_InteractiveOneFlags(f, p, NULL); } #undef PyRun_InteractiveLoop -int +PyAPI_FUNC(int) PyRun_InteractiveLoop(FILE *f, const char *p) { return PyRun_InteractiveLoopFlags(f, p, NULL); From webhook-mailer at python.org Tue Nov 5 02:07:59 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 05 Nov 2019 07:07:59 -0000 Subject: [Python-checkins] Convert argument to snake_case (GH-16990) (GH-17033) Message-ID: https://github.com/python/cpython/commit/0eb6fefad7c753a186cf51f0dc52416a1a8d6d51 commit: 0eb6fefad7c753a186cf51f0dc52416a1a8d6d51 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-04T23:07:24-08:00 summary: Convert argument to snake_case (GH-16990) (GH-17033) (cherry picked from commit 99b7701978d1fdc81e10c31d1ad8cce2c0c2d848) Co-authored-by: ????? ?????????? files: M Doc/library/itertools.rst diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 8d134d4380659..3e5a673898106 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -766,9 +766,9 @@ which incur interpreter overhead. def dotproduct(vec1, vec2): return sum(map(operator.mul, vec1, vec2)) - def flatten(listOfLists): + def flatten(list_of_lists): "Flatten one level of nesting" - return chain.from_iterable(listOfLists) + return chain.from_iterable(list_of_lists) def repeatfunc(func, times=None, *args): """Repeat calls to func with specified arguments. From webhook-mailer at python.org Tue Nov 5 06:09:20 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 05 Nov 2019 11:09:20 -0000 Subject: [Python-checkins] _json.c: use Py_UNUSED() macro (GH-17053) Message-ID: https://github.com/python/cpython/commit/fbbfcce2d6c5ab16324b36572966e9605e7dc192 commit: fbbfcce2d6c5ab16324b36572966e9605e7dc192 branch: master author: Victor Stinner committer: GitHub date: 2019-11-05T11:44:28+01:00 summary: _json.c: use Py_UNUSED() macro (GH-17053) Remove UNUSED macro: use Py_UNUSED() macro instead. files: M Modules/_json.c diff --git a/Modules/_json.c b/Modules/_json.c index 54ac605fd7ef4..439414fd59e62 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -12,12 +12,6 @@ #include "structmember.h" #include "pycore_accu.h" -#ifdef __GNUC__ -#define UNUSED __attribute__((__unused__)) -#else -#define UNUSED -#endif - #define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) #define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) #define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) @@ -78,7 +72,7 @@ static PyMemberDef encoder_members[] = { static PyObject * ascii_escape_unicode(PyObject *pystr); static PyObject * -py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr); +py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr); void init_json(void); static PyObject * scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); @@ -562,7 +556,7 @@ PyDoc_STRVAR(pydoc_scanstring, ); static PyObject * -py_scanstring(PyObject* self UNUSED, PyObject *args) +py_scanstring(PyObject* Py_UNUSED(self), PyObject *args) { PyObject *pystr; PyObject *rval; @@ -591,7 +585,7 @@ PyDoc_STRVAR(pydoc_encode_basestring_ascii, ); static PyObject * -py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) +py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr) { PyObject *rval; /* Return an ASCII-only JSON representation of a Python string */ @@ -616,7 +610,7 @@ PyDoc_STRVAR(pydoc_encode_basestring, ); static PyObject * -py_encode_basestring(PyObject* self UNUSED, PyObject *pystr) +py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr) { PyObject *rval; /* Return a JSON representation of a Python string */ From webhook-mailer at python.org Tue Nov 5 08:36:16 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 13:36:16 -0000 Subject: [Python-checkins] [3.7] bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) (GH-17027) Message-ID: https://github.com/python/cpython/commit/4342af00d87de0a0d0ef3bfda4d6edb08ac2427a commit: 4342af00d87de0a0d0ef3bfda4d6edb08ac2427a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-05T05:36:09-08:00 summary: [3.7] bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) (GH-17027) This was never intented to be called manually from PyInit_*. Also, clarify PyState_RemoveModule return value. (cherry picked from commit 9bc94eca0c69a551f928692364a99e9b67c4a45b) Co-authored-by: Petr Viktorin https://bugs.python.org/issue38159 Automerge-Triggered-By: @encukou files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 60c1bf48c60cb..a06e791e38f2e 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -485,10 +485,21 @@ since multiple such modules can be created from a single definition. Only effective on modules created using single-phase initialization. + Python calls ``PyState_AddModule`` automatically after importing a module, + so it is unnecessary (but harmless) to call it from module initialization + code. An explicit call is needed only if the module's own init code + subsequently calls ``PyState_FindModule``. + The function is mainly intended for implementing alternative import + mechanisms (either by calling it directly, or by referring to its + implementation for details of the required state updates). + + Return 0 on success or -1 on failure. + .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. + Return 0 on success or -1 on failure. .. versionadded:: 3.3 From webhook-mailer at python.org Tue Nov 5 08:53:17 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 05 Nov 2019 13:53:17 -0000 Subject: [Python-checkins] Update interpreter.rst (GH-17059) Message-ID: https://github.com/python/cpython/commit/5e01a6542a1beb552a17e16b71dc0ba9fc6adcfb commit: 5e01a6542a1beb552a17e16b71dc0ba9fc6adcfb branch: master author: Jules Lasne (jlasne) committer: Victor Stinner date: 2019-11-05T14:20:38+01:00 summary: Update interpreter.rst (GH-17059) Fixed what seemed to be a weird phrasing. files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index ffab8fa4e0d84..b78d2960ac543 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -23,7 +23,7 @@ is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) -On Windows machines where you have installed from the :ref:`Microsoft Store +On Windows machines where you have installed Python from the :ref:`Microsoft Store `, the :file:`python3.9` command will be available. If you have the :ref:`py.exe launcher ` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. From webhook-mailer at python.org Tue Nov 5 09:02:19 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 05 Nov 2019 14:02:19 -0000 Subject: [Python-checkins] [3.7] [3.8] Update interpreter.rst (GH-17059) (GH-17060) (GH-17061) Message-ID: https://github.com/python/cpython/commit/1bfc56759fc4c1317fd6b7f3e8c094cbc5a010e0 commit: 1bfc56759fc4c1317fd6b7f3e8c094cbc5a010e0 branch: 3.7 author: Jules Lasne (jlasne) committer: Victor Stinner date: 2019-11-05T15:02:09+01:00 summary: [3.7] [3.8] Update interpreter.rst (GH-17059) (GH-17060) (GH-17061) Fixed what seemed to be a weird phrasing. (cherry picked from commit 5e01a6542a1beb552a17e16b71dc0ba9fc6adcfb) Co-authored-by: Jules Lasne (jlasne) . (cherry picked from commit 1eac437e8da106a626efffe9fce1cb47dbf5be35) Co-authored-by: Jules Lasne (jlasne) files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index daa4173642447..3bacab35da339 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -23,7 +23,7 @@ is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) -On Windows machines where you have installed from the :ref:`Microsoft Store +On Windows machines where you have installed Python from the :ref:`Microsoft Store `, the :file:`python3.7` command will be available. If you have the :ref:`py.exe launcher ` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. From webhook-mailer at python.org Tue Nov 5 09:12:57 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 14:12:57 -0000 Subject: [Python-checkins] [3.8] bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) (GH-17026) Message-ID: https://github.com/python/cpython/commit/1270d2cf1d17bfa581bf2a19f82c8cb43bf793d9 commit: 1270d2cf1d17bfa581bf2a19f82c8cb43bf793d9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-05T05:35:56-08:00 summary: [3.8] bpo-38159: Clarify documentation of PyState_AddModule (GH-16101) (GH-17026) This was never intented to be called manually from PyInit_*. Also, clarify PyState_RemoveModule return value. (cherry picked from commit 9bc94eca0c69a551f928692364a99e9b67c4a45b) Co-authored-by: Petr Viktorin https://bugs.python.org/issue38159 Automerge-Triggered-By: @encukou files: M Doc/c-api/module.rst diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 46306b3917cce..57902a9c7f838 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -485,10 +485,21 @@ since multiple such modules can be created from a single definition. Only effective on modules created using single-phase initialization. + Python calls ``PyState_AddModule`` automatically after importing a module, + so it is unnecessary (but harmless) to call it from module initialization + code. An explicit call is needed only if the module's own init code + subsequently calls ``PyState_FindModule``. + The function is mainly intended for implementing alternative import + mechanisms (either by calling it directly, or by referring to its + implementation for details of the required state updates). + + Return 0 on success or -1 on failure. + .. versionadded:: 3.3 .. c:function:: int PyState_RemoveModule(PyModuleDef *def) Removes the module object created from *def* from the interpreter state. + Return 0 on success or -1 on failure. .. versionadded:: 3.3 From webhook-mailer at python.org Tue Nov 5 09:38:35 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 05 Nov 2019 14:38:35 -0000 Subject: [Python-checkins] [3.8] Update interpreter.rst (GH-17059) (GH-17060) Message-ID: https://github.com/python/cpython/commit/1eac437e8da106a626efffe9fce1cb47dbf5be35 commit: 1eac437e8da106a626efffe9fce1cb47dbf5be35 branch: 3.8 author: Jules Lasne (jlasne) committer: Victor Stinner date: 2019-11-05T14:51:48+01:00 summary: [3.8] Update interpreter.rst (GH-17059) (GH-17060) Fixed what seemed to be a weird phrasing. (cherry picked from commit 5e01a6542a1beb552a17e16b71dc0ba9fc6adcfb) Co-authored-by: Jules Lasne (jlasne) files: M Doc/tutorial/interpreter.rst diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 320befdbb9d0c..501fb6a785624 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -23,7 +23,7 @@ is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) -On Windows machines where you have installed from the :ref:`Microsoft Store +On Windows machines where you have installed Python from the :ref:`Microsoft Store `, the :file:`python3.8` command will be available. If you have the :ref:`py.exe launcher ` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. From webhook-mailer at python.org Tue Nov 5 10:59:29 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 15:59:29 -0000 Subject: [Python-checkins] bpo-35381 Remove all static state from posixmodule (GH-15892) Message-ID: https://github.com/python/cpython/commit/b3966639d28313809774ca3859a347b9007be8d2 commit: b3966639d28313809774ca3859a347b9007be8d2 branch: master author: Eddie Elizondo committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-05T07:16:14-08:00 summary: bpo-35381 Remove all static state from posixmodule (GH-15892) After #9665, this moves the remaining types in posixmodule to be heap-allocated to make it compatible with PEP384 as well as modifying all the type accessors to fully make the type opaque. The original PR that got messed up a rebase: https://github.com/python/cpython/pull/10854. All the issues in that commit have now been addressed since https://github.com/python/cpython/pull/11661 got committed. This change also removes any state from the data segment and onto the module state itself. https://bugs.python.org/issue35381 Automerge-Triggered-By: @encukou files: A Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst M Lib/test/test_os.py M Modules/clinic/posixmodule.c.h M Modules/posixmodule.c diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index d2bd9c2f232f1..bf40cb1e8fa7d 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3638,6 +3638,24 @@ def test_os_all(self): self.assertIn('walk', os.__all__) +class TestDirEntry(unittest.TestCase): + def setUp(self): + self.path = os.path.realpath(support.TESTFN) + self.addCleanup(support.rmtree, self.path) + os.mkdir(self.path) + + def test_uninstantiable(self): + self.assertRaises(TypeError, os.DirEntry) + + def test_unpickable(self): + filename = create_file(os.path.join(self.path, "file.txt"), b'python') + entry = [entry for entry in os.scandir(self.path)].pop() + self.assertIsInstance(entry, os.DirEntry) + self.assertEqual(entry.name, "file.txt") + import pickle + self.assertRaises(TypeError, pickle.dumps, entry, filename) + + class TestScandir(unittest.TestCase): check_no_resource_warning = support.check_no_resource_warning @@ -3672,6 +3690,18 @@ def assert_stat_equal(self, stat1, stat2, skip_fields): else: self.assertEqual(stat1, stat2) + def test_uninstantiable(self): + scandir_iter = os.scandir(self.path) + self.assertRaises(TypeError, type(scandir_iter)) + scandir_iter.close() + + def test_unpickable(self): + filename = self.create_file("file.txt") + scandir_iter = os.scandir(self.path) + import pickle + self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename) + scandir_iter.close() + def check_entry(self, entry, name, is_dir, is_file, is_symlink): self.assertIsInstance(entry, os.DirEntry) self.assertEqual(entry.name, name) diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst new file mode 100644 index 0000000000000..a7efce468c6d8 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst @@ -0,0 +1,2 @@ +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 561cbb0ca82ab..3dada674fbab0 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2838,7 +2838,7 @@ PyDoc_STRVAR(os_sched_param__doc__, "sched_param(sched_priority)\n" "--\n" "\n" -"Current has only one field: sched_priority\");\n" +"Currently has only one field: sched_priority\n" "\n" " sched_priority\n" " A scheduling parameter."); @@ -8731,4 +8731,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=fe7897441fed5402 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6e67d475eef00c4 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index dcd90d3a5152d..6d837c6552f49 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -217,6 +217,7 @@ corresponding Unix manual entries for more information on calls."); #endif /* _MSC_VER */ #endif /* ! __WATCOMC__ || __QNX__ */ +_Py_IDENTIFIER(__fspath__); /*[clinic input] # one of the few times we lie about this name! @@ -537,7 +538,7 @@ _Py_Uid_Converter(PyObject *obj, void *p) if (index == NULL) { PyErr_Format(PyExc_TypeError, "uid should be integer, not %.200s", - Py_TYPE(obj)->tp_name); + _PyType_Name(Py_TYPE(obj))); return 0; } @@ -643,7 +644,7 @@ _Py_Gid_Converter(PyObject *obj, void *p) if (index == NULL) { PyErr_Format(PyExc_TypeError, "gid should be integer, not %.200s", - Py_TYPE(obj)->tp_name); + _PyType_Name(Py_TYPE(obj))); return 0; } @@ -810,11 +811,37 @@ dir_fd_converter(PyObject *o, void *p) else { PyErr_Format(PyExc_TypeError, "argument should be integer or None, not %.200s", - Py_TYPE(o)->tp_name); + _PyType_Name(Py_TYPE(o))); return 0; } } +typedef struct { + PyObject *billion; + PyObject *posix_putenv_garbage; + PyObject *DirEntryType; + PyObject *ScandirIteratorType; +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + PyObject *SchedParamType; +#endif + PyObject *StatResultType; + PyObject *StatVFSResultType; + PyObject *TerminalSizeType; + PyObject *TimesResultType; + PyObject *UnameResultType; +#if defined(HAVE_WAITID) && !defined(__APPLE__) + PyObject *WaitidResultType; +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + PyObject *struct_rusage; +#endif + PyObject *st_mode; +} _posixstate; + +static struct PyModuleDef posixmodule; + +#define _posixstate(o) ((_posixstate *)PyModule_GetState(o)) +#define _posixstate_global ((_posixstate *)PyModule_GetState(PyState_FindModule(&posixmodule))) /* * A PyArg_ParseTuple "converter" function @@ -984,7 +1011,6 @@ path_converter(PyObject *o, void *p) if (!is_index && !is_buffer && !is_unicode && !is_bytes) { /* Inline PyOS_FSPath() for better error messages. */ - _Py_IDENTIFIER(__fspath__); PyObject *func, *res; func = _PyObject_LookupSpecial(o, &PyId___fspath__); @@ -1005,8 +1031,8 @@ path_converter(PyObject *o, void *p) else { PyErr_Format(PyExc_TypeError, "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", Py_TYPE(o)->tp_name, - Py_TYPE(res)->tp_name); + "not %.200s", _PyType_Name(Py_TYPE(o)), + _PyType_Name(Py_TYPE(res))); Py_DECREF(res); goto error_exit; } @@ -1058,7 +1084,7 @@ path_converter(PyObject *o, void *p) path->allow_fd ? "string, bytes, os.PathLike or integer" : path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", - Py_TYPE(o)->tp_name)) { + _PyType_Name(Py_TYPE(o)))) { goto error_exit; } bytes = PyBytes_FromObject(o); @@ -1089,7 +1115,7 @@ path_converter(PyObject *o, void *p) path->allow_fd ? "string, bytes, os.PathLike or integer" : path->nullable ? "string, bytes, os.PathLike or None" : "string, bytes or os.PathLike", - Py_TYPE(o)->tp_name); + _PyType_Name(Py_TYPE(o))); goto error_exit; } @@ -2047,14 +2073,6 @@ static PyStructSequence_Desc waitid_result_desc = { waitid_result_fields, 5 }; -static PyTypeObject* WaitidResultType; -#endif - -static int initialized; -static PyTypeObject* StatResultType; -static PyTypeObject* StatVFSResultType; -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) -static PyTypeObject* SchedParamType; #endif static newfunc structseq_new; @@ -2080,8 +2098,61 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject*)result; } +static int +_posix_clear(PyObject *module) +{ + Py_CLEAR(_posixstate(module)->billion); + Py_CLEAR(_posixstate(module)->posix_putenv_garbage); + Py_CLEAR(_posixstate(module)->DirEntryType); + Py_CLEAR(_posixstate(module)->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_CLEAR(_posixstate(module)->SchedParamType); +#endif + Py_CLEAR(_posixstate(module)->StatResultType); + Py_CLEAR(_posixstate(module)->StatVFSResultType); + Py_CLEAR(_posixstate(module)->TerminalSizeType); + Py_CLEAR(_posixstate(module)->TimesResultType); + Py_CLEAR(_posixstate(module)->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_CLEAR(_posixstate(module)->WaitidResultType); +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_CLEAR(_posixstate(module)->struct_rusage); +#endif + Py_CLEAR(_posixstate(module)->st_mode); + return 0; +} -static PyObject *billion = NULL; +static int +_posix_traverse(PyObject *module, visitproc visit, void *arg) +{ + Py_VISIT(_posixstate(module)->billion); + Py_VISIT(_posixstate(module)->posix_putenv_garbage); + Py_VISIT(_posixstate(module)->DirEntryType); + Py_VISIT(_posixstate(module)->ScandirIteratorType); +#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) + Py_VISIT(_posixstate(module)->SchedParamType); +#endif + Py_VISIT(_posixstate(module)->StatResultType); + Py_VISIT(_posixstate(module)->StatVFSResultType); + Py_VISIT(_posixstate(module)->TerminalSizeType); + Py_VISIT(_posixstate(module)->TimesResultType); + Py_VISIT(_posixstate(module)->UnameResultType); +#if defined(HAVE_WAITID) && !defined(__APPLE__) + Py_VISIT(_posixstate(module)->WaitidResultType); +#endif +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + Py_VISIT(_posixstate(module)->struct_rusage); +#endif + Py_VISIT(_posixstate(module)->st_mode); + return 0; +} + +static void +_posix_free(void *module) +{ + _posix_clear((PyObject *)module); +} static void fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) @@ -2095,7 +2166,7 @@ fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) if (!(s && ns_fractional)) goto exit; - s_in_ns = PyNumber_Multiply(s, billion); + s_in_ns = PyNumber_Multiply(s, _posixstate_global->billion); if (!s_in_ns) goto exit; @@ -2128,7 +2199,8 @@ static PyObject* _pystat_fromstructstat(STRUCT_STAT *st) { unsigned long ansec, mnsec, cnsec; - PyObject *v = PyStructSequence_New(StatResultType); + PyObject *StatResultType = _posixstate_global->StatResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatResultType); if (v == NULL) return NULL; @@ -4505,15 +4577,12 @@ or via the attributes sysname, nodename, release, version, and machine.\n\ See os.uname for more information."); static PyStructSequence_Desc uname_result_desc = { - "uname_result", /* name */ + MODNAME ".uname_result", /* name */ uname_result__doc__, /* doc */ uname_result_fields, 5 }; -static PyTypeObject* UnameResultType; - - #ifdef HAVE_UNAME /*[clinic input] os.uname @@ -4539,7 +4608,8 @@ os_uname_impl(PyObject *module) if (res < 0) return posix_error(); - value = PyStructSequence_New(UnameResultType); + PyObject *UnameResultType = _posixstate(module)->UnameResultType; + value = PyStructSequence_New((PyTypeObject *)UnameResultType); if (value == NULL) return NULL; @@ -4720,13 +4790,13 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) { int result = 0; PyObject *divmod; - divmod = PyNumber_Divmod(py_long, billion); + divmod = PyNumber_Divmod(py_long, _posixstate_global->billion); if (!divmod) goto exit; if (!PyTuple_Check(divmod) || PyTuple_GET_SIZE(divmod) != 2) { PyErr_Format(PyExc_TypeError, "%.200s.__divmod__() must return a 2-tuple, not %.200s", - Py_TYPE(py_long)->tp_name, Py_TYPE(divmod)->tp_name); + _PyType_Name(Py_TYPE(py_long)), _PyType_Name(Py_TYPE(divmod))); goto exit; } *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); @@ -5973,7 +6043,7 @@ check_null_or_callable(PyObject *obj, const char* obj_name) { if (obj && !PyCallable_Check(obj)) { PyErr_Format(PyExc_TypeError, "'%s' must be callable, not %s", - obj_name, Py_TYPE(obj)->tp_name); + obj_name, _PyType_Name(Py_TYPE(obj))); return -1; } return 0; @@ -6177,12 +6247,12 @@ os.sched_param.__new__ sched_priority: object A scheduling parameter. -Current has only one field: sched_priority"); +Currently has only one field: sched_priority [clinic start generated code]*/ static PyObject * os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) -/*[clinic end generated code: output=48f4067d60f48c13 input=ab4de35a9a7811f2]*/ +/*[clinic end generated code: output=48f4067d60f48c13 input=eb42909a2c0e3e6c]*/ { PyObject *res; @@ -6194,7 +6264,6 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) return res; } - PyDoc_VAR(os_sched_param__doc__); static PyStructSequence_Field sched_param_fields[] = { @@ -6214,7 +6283,8 @@ convert_sched_param(PyObject *param, struct sched_param *res) { long priority; - if (Py_TYPE(param) != SchedParamType) { + PyObject *SchedParamType = _posixstate_global->SchedParamType; + if (Py_TYPE(param) != (PyTypeObject *)SchedParamType) { PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); return 0; } @@ -6285,7 +6355,8 @@ os_sched_getparam_impl(PyObject *module, pid_t pid) if (sched_getparam(pid, ¶m)) return posix_error(); - result = PyStructSequence_New(SchedParamType); + PyObject *SchedParamType = _posixstate_global->SchedParamType; + result = PyStructSequence_New((PyTypeObject *)SchedParamType); if (!result) return NULL; priority = PyLong_FromLong(param.sched_priority); @@ -7494,8 +7565,7 @@ static PyObject * wait_helper(pid_t pid, int status, struct rusage *ru) { PyObject *result; - static PyObject *struct_rusage; - _Py_IDENTIFIER(struct_rusage); + PyObject *struct_rusage; if (pid == -1) return posix_error(); @@ -7506,15 +7576,13 @@ wait_helper(pid_t pid, int status, struct rusage *ru) memset(ru, 0, sizeof(*ru)); } - if (struct_rusage == NULL) { - PyObject *m = PyImport_ImportModuleNoBlock("resource"); - if (m == NULL) - return NULL; - struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage); - Py_DECREF(m); - if (struct_rusage == NULL) - return NULL; - } + PyObject *m = PyImport_ImportModuleNoBlock("resource"); + if (m == NULL) + return NULL; + struct_rusage = PyObject_GetAttr(m, _posixstate_global->struct_rusage); + Py_DECREF(m); + if (struct_rusage == NULL) + return NULL; /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ result = PyStructSequence_New((PyTypeObject*) struct_rusage); @@ -7668,7 +7736,8 @@ os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options) if (si.si_pid == 0) Py_RETURN_NONE; - result = PyStructSequence_New(WaitidResultType); + PyObject *WaitidResultType = _posixstate(module)->WaitidResultType; + result = PyStructSequence_New((PyTypeObject *)WaitidResultType); if (!result) return NULL; @@ -8119,8 +8188,6 @@ static PyStructSequence_Desc times_result_desc = { 5 }; -static PyTypeObject* TimesResultType; - #ifdef MS_WINDOWS #define HAVE_TIMES /* mandatory, for the method table */ #endif @@ -8132,7 +8199,8 @@ build_times_result(double user, double system, double children_user, double children_system, double elapsed) { - PyObject *value = PyStructSequence_New(TimesResultType); + PyObject *TimesResultType = _posixstate_global->TimesResultType; + PyObject *value = PyStructSequence_New((PyTypeObject *)TimesResultType); if (value == NULL) return NULL; @@ -9953,10 +10021,6 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, #ifdef HAVE_PUTENV -/* Save putenv() parameters as values here, so we can collect them when they - * get re-set with another call for the same key. */ -static PyObject *posix_putenv_garbage; - static void posix_putenv_garbage_setitem(PyObject *name, PyObject *value) { @@ -9964,7 +10028,7 @@ posix_putenv_garbage_setitem(PyObject *name, PyObject *value) * this will cause previous value to be collected. This has to * happen after the real putenv() call because the old value * was still accessible until then. */ - if (PyDict_SetItem(posix_putenv_garbage, name, value)) + if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value)) /* really not much we can do; just leak */ PyErr_Clear(); else @@ -10101,7 +10165,7 @@ os_unsetenv_impl(PyObject *module, PyObject *name) * happen after the real unsetenv() call because the * old value was still accessible until then. */ - if (PyDict_DelItem(posix_putenv_garbage, name)) { + if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) { /* really not much we can do; just leak */ if (!PyErr_ExceptionMatches(PyExc_KeyError)) { return NULL; @@ -10312,7 +10376,8 @@ os_WSTOPSIG_impl(PyObject *module, int status) static PyObject* _pystatvfs_fromstructstatvfs(struct statvfs st) { - PyObject *v = PyStructSequence_New(StatVFSResultType); + PyObject *StatVFSResultType = _posixstate_global->StatVFSResultType; + PyObject *v = PyStructSequence_New((PyTypeObject *)StatVFSResultType); if (v == NULL) return NULL; @@ -12089,8 +12154,6 @@ os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) /* Terminal size querying */ -static PyTypeObject* TerminalSizeType; - PyDoc_STRVAR(TerminalSize_docstring, "A tuple of (columns, lines) for holding terminal window size"); @@ -12181,7 +12244,8 @@ get_terminal_size(PyObject *self, PyObject *args) } #endif /* TERMSIZE_USE_CONIO */ - termsize = PyStructSequence_New(TerminalSizeType); + PyObject *TerminalSizeType = _posixstate(self)->TerminalSizeType; + termsize = PyStructSequence_New((PyTypeObject *)TerminalSizeType); if (termsize == NULL) return NULL; PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); @@ -12379,9 +12443,9 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] -class os.DirEntry "DirEntry *" "&DirEntryType" +class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ typedef struct { PyObject_HEAD @@ -12402,14 +12466,25 @@ typedef struct { #endif } DirEntry; +static PyObject * +_disabled_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", _PyType_Name(type)); + return NULL; +} + static void DirEntry_dealloc(DirEntry *entry) { + PyTypeObject *tp = Py_TYPE(entry); Py_XDECREF(entry->name); Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); - Py_TYPE(entry)->tp_free((PyObject *)entry); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(entry); + Py_DECREF(tp); } /* Forward reference */ @@ -12538,7 +12613,6 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits #ifdef MS_WINDOWS unsigned long dir_bits; #endif - _Py_IDENTIFIER(st_mode); #ifdef MS_WINDOWS is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; @@ -12561,7 +12635,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits } goto error; } - st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode); + st_mode = PyObject_GetAttr(stat, _posixstate_global->st_mode); if (!st_mode) goto error; @@ -12709,39 +12783,24 @@ static PyMethodDef DirEntry_methods[] = { {NULL} }; -static PyTypeObject DirEntryType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".DirEntry", /* tp_name */ - sizeof(DirEntry), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)DirEntry_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)DirEntry_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - DirEntry_methods, /* tp_methods */ - DirEntry_members, /* tp_members */ +static PyType_Slot DirEntryType_slots[] = { + {Py_tp_new, _disabled_new}, + {Py_tp_dealloc, DirEntry_dealloc}, + {Py_tp_repr, DirEntry_repr}, + {Py_tp_methods, DirEntry_methods}, + {Py_tp_members, DirEntry_members}, + {0, 0}, +}; + +static PyType_Spec DirEntryType_spec = { + MODNAME ".DirEntry", + sizeof(DirEntry), + 0, + Py_TPFLAGS_DEFAULT, + DirEntryType_slots }; + #ifdef MS_WINDOWS static wchar_t * @@ -12785,7 +12844,8 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + PyObject *DirEntryType = _posixstate_global->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12872,7 +12932,8 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, DirEntry *entry; char *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + PyObject *DirEntryType = _posixstate_global->DirEntryType; + entry = PyObject_New(DirEntry, (PyTypeObject *)DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -13134,10 +13195,13 @@ ScandirIterator_finalize(ScandirIterator *iterator) static void ScandirIterator_dealloc(ScandirIterator *iterator) { + PyTypeObject *tp = Py_TYPE(iterator); if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; - Py_TYPE(iterator)->tp_free((PyObject *)iterator); + freefunc free_func = PyType_GetSlot(tp, Py_tp_free); + free_func(iterator); + Py_DECREF(tp); } static PyMethodDef ScandirIterator_methods[] = { @@ -13147,56 +13211,22 @@ static PyMethodDef ScandirIterator_methods[] = { {NULL} }; -static PyTypeObject ScandirIteratorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".ScandirIterator", /* tp_name */ - sizeof(ScandirIterator), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)ScandirIterator_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ - ScandirIterator_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)ScandirIterator_finalize, /* tp_finalize */ +static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_new, _disabled_new}, + {Py_tp_dealloc, ScandirIterator_dealloc}, + {Py_tp_finalize, ScandirIterator_finalize}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, ScandirIterator_iternext}, + {Py_tp_methods, ScandirIterator_methods}, + {0, 0}, +}; + +static PyType_Spec ScandirIteratorType_spec = { + MODNAME ".ScandirIterator", + sizeof(ScandirIterator), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + ScandirIteratorType_slots }; /*[clinic input] @@ -13232,7 +13262,8 @@ os_scandir_impl(PyObject *module, path_t *path) return NULL; } - iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); + PyObject *ScandirIteratorType = _posixstate(module)->ScandirIteratorType; + iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType); if (!iterator) return NULL; @@ -13322,7 +13353,6 @@ PyOS_FSPath(PyObject *path) { /* For error message reasons, this function is manually inlined in path_converter(). */ - _Py_IDENTIFIER(__fspath__); PyObject *func = NULL; PyObject *path_repr = NULL; @@ -13336,7 +13366,7 @@ PyOS_FSPath(PyObject *path) return PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, " "not %.200s", - Py_TYPE(path)->tp_name); + _PyType_Name(Py_TYPE(path))); } path_repr = _PyObject_CallNoArg(func); @@ -13348,8 +13378,8 @@ PyOS_FSPath(PyObject *path) if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { PyErr_Format(PyExc_TypeError, "expected %.200s.__fspath__() to return str or bytes, " - "not %.200s", Py_TYPE(path)->tp_name, - Py_TYPE(path_repr)->tp_name); + "not %.200s", _PyType_Name(Py_TYPE(path)), + _PyType_Name(Py_TYPE(path_repr))); Py_DECREF(path_repr); return NULL; } @@ -14258,12 +14288,12 @@ static struct PyModuleDef posixmodule = { PyModuleDef_HEAD_INIT, MODNAME, posix__doc__, - -1, + sizeof(_posixstate), posix_methods, NULL, - NULL, - NULL, - NULL + _posix_traverse, + _posix_clear, + _posix_free, }; @@ -14408,6 +14438,12 @@ INITFUNC(void) PyObject *list; const char * const *trace; + m = PyState_FindModule(&posixmodule); + if (m != NULL) { + Py_INCREF(m); + return m; + } + m = PyModule_Create(&posixmodule); if (m == NULL) return NULL; @@ -14429,94 +14465,106 @@ INITFUNC(void) PyModule_AddObject(m, "error", PyExc_OSError); #ifdef HAVE_PUTENV - if (posix_putenv_garbage == NULL) - posix_putenv_garbage = PyDict_New(); + /* Save putenv() parameters as values here, so we can collect them when they + * get re-set with another call for the same key. */ + _posixstate(m)->posix_putenv_garbage = PyDict_New(); #endif - if (!initialized) { #if defined(HAVE_WAITID) && !defined(__APPLE__) - waitid_result_desc.name = MODNAME ".waitid_result"; - WaitidResultType = PyStructSequence_NewType(&waitid_result_desc); - if (WaitidResultType == NULL) { - return NULL; - } + waitid_result_desc.name = MODNAME ".waitid_result"; + PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc); + if (WaitidResultType == NULL) { + return NULL; + } + Py_INCREF(WaitidResultType); + PyModule_AddObject(m, "waitid_result", WaitidResultType); + _posixstate(m)->WaitidResultType = WaitidResultType; #endif - stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ - stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; - stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; - stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; - StatResultType = PyStructSequence_NewType(&stat_result_desc); - if (StatResultType == NULL) { - return NULL; - } - structseq_new = StatResultType->tp_new; - StatResultType->tp_new = statresult_new; + stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ + stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; + stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; + stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; + PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc); + if (StatResultType == NULL) { + return NULL; + } + Py_INCREF(StatResultType); + PyModule_AddObject(m, "stat_result", StatResultType); + _posixstate(m)->StatResultType = StatResultType; + structseq_new = ((PyTypeObject *)StatResultType)->tp_new; + ((PyTypeObject *)StatResultType)->tp_new = statresult_new; - statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ - StatVFSResultType = PyStructSequence_NewType(&statvfs_result_desc); - if (StatVFSResultType == NULL) { - return NULL; - } + statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ + PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); + if (StatVFSResultType == NULL) { + return NULL; + } + Py_INCREF(StatVFSResultType); + PyModule_AddObject(m, "statvfs_result", StatVFSResultType); + _posixstate(m)->StatVFSResultType = StatVFSResultType; #ifdef NEED_TICKS_PER_SECOND # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - ticks_per_second = sysconf(_SC_CLK_TCK); + ticks_per_second = sysconf(_SC_CLK_TCK); # elif defined(HZ) - ticks_per_second = HZ; + ticks_per_second = HZ; # else - ticks_per_second = 60; /* magic fallback value; may be bogus */ + ticks_per_second = 60; /* magic fallback value; may be bogus */ # endif #endif #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) - sched_param_desc.name = MODNAME ".sched_param"; - SchedParamType = PyStructSequence_NewType(&sched_param_desc); - if (SchedParamType == NULL) { - return NULL; - } - SchedParamType->tp_new = os_sched_param; + sched_param_desc.name = MODNAME ".sched_param"; + PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc); + if (SchedParamType == NULL) { + return NULL; + } + Py_INCREF(SchedParamType); + PyModule_AddObject(m, "sched_param", SchedParamType); + _posixstate(m)->SchedParamType = SchedParamType; + ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param; #endif - /* initialize TerminalSize_info */ - TerminalSizeType = PyStructSequence_NewType(&TerminalSize_desc); - if (TerminalSizeType == NULL) { - return NULL; - } + /* initialize TerminalSize_info */ + PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc); + if (TerminalSizeType == NULL) { + return NULL; + } + Py_INCREF(TerminalSizeType); + PyModule_AddObject(m, "terminal_size", TerminalSizeType); + _posixstate(m)->TerminalSizeType = TerminalSizeType; - /* initialize scandir types */ - if (PyType_Ready(&ScandirIteratorType) < 0) - return NULL; - if (PyType_Ready(&DirEntryType) < 0) - return NULL; + /* initialize scandir types */ + PyObject *ScandirIteratorType = PyType_FromSpec(&ScandirIteratorType_spec); + if (ScandirIteratorType == NULL) { + return NULL; } -#if defined(HAVE_WAITID) && !defined(__APPLE__) - Py_INCREF((PyObject*) WaitidResultType); - PyModule_AddObject(m, "waitid_result", (PyObject*) WaitidResultType); -#endif - Py_INCREF((PyObject*) StatResultType); - PyModule_AddObject(m, "stat_result", (PyObject*) StatResultType); - Py_INCREF((PyObject*) StatVFSResultType); - PyModule_AddObject(m, "statvfs_result", - (PyObject*) StatVFSResultType); + _posixstate(m)->ScandirIteratorType = ScandirIteratorType; -#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) - Py_INCREF(SchedParamType); - PyModule_AddObject(m, "sched_param", (PyObject *)SchedParamType); -#endif + PyObject *DirEntryType = PyType_FromSpec(&DirEntryType_spec); + if (DirEntryType == NULL) { + return NULL; + } + Py_INCREF(DirEntryType); + PyModule_AddObject(m, "DirEntry", DirEntryType); + _posixstate(m)->DirEntryType = DirEntryType; times_result_desc.name = MODNAME ".times_result"; - TimesResultType = PyStructSequence_NewType(×_result_desc); + PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(×_result_desc); if (TimesResultType == NULL) { return NULL; } - PyModule_AddObject(m, "times_result", (PyObject *)TimesResultType); + Py_INCREF(TimesResultType); + PyModule_AddObject(m, "times_result", TimesResultType); + _posixstate(m)->TimesResultType = TimesResultType; - uname_result_desc.name = MODNAME ".uname_result"; - UnameResultType = PyStructSequence_NewType(&uname_result_desc); + PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc); if (UnameResultType == NULL) { return NULL; } + Py_INCREF(UnameResultType); PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); + _posixstate(m)->UnameResultType = (PyObject *)UnameResultType; #ifdef __APPLE__ /* @@ -14556,11 +14604,15 @@ INITFUNC(void) #endif /* __APPLE__ */ - Py_INCREF(TerminalSizeType); - PyModule_AddObject(m, "terminal_size", (PyObject*)TerminalSizeType); - - billion = PyLong_FromLong(1000000000); - if (!billion) + if ((_posixstate(m)->billion = PyLong_FromLong(1000000000)) == NULL) + return NULL; +#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) + _posixstate(m)->struct_rusage = PyUnicode_InternFromString("struct_rusage"); + if (_posixstate(m)->struct_rusage == NULL) + return NULL; +#endif + _posixstate(m)->st_mode = PyUnicode_InternFromString("st_mode"); + if (_posixstate(m)->st_mode == NULL) return NULL; /* suppress "function not used" warnings */ @@ -14590,11 +14642,6 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - Py_INCREF((PyObject *) &DirEntryType); - PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); - - initialized = 1; - return m; } From webhook-mailer at python.org Tue Nov 5 11:53:53 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 05 Nov 2019 16:53:53 -0000 Subject: [Python-checkins] bpo-37645: add new function _PyObject_FunctionStr() (GH-14890) Message-ID: https://github.com/python/cpython/commit/bf17d41826a8bb4bc1e34ba6345da98aac779e41 commit: bf17d41826a8bb4bc1e34ba6345da98aac779e41 branch: master author: Jeroen Demeyer committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-05T07:48:04-08:00 summary: bpo-37645: add new function _PyObject_FunctionStr() (GH-14890) Additional note: the `method_check_args` function in `Objects/descrobject.c` is written in such a way that it applies to all kinds of descriptors. In particular, a future re-implementation of `wrapper_descriptor` could use that code. CC @vstinner @encukou https://bugs.python.org/issue37645 Automerge-Triggered-By: @encukou files: A Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst M Doc/c-api/object.rst M Include/cpython/object.h M Lib/test/test_call.py M Lib/test/test_descr.py M Lib/test/test_extcall.py M Lib/test/test_unpack_ex.py M Objects/descrobject.c M Objects/methodobject.c M Objects/object.c M Python/ceval.c diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 9d1155184725b..7d7a3be02fabc 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -196,6 +196,7 @@ Object Protocol This function now includes a debug assertion to help ensure that it does not silently discard an active exception. + .. c:function:: PyObject* PyObject_Bytes(PyObject *o) .. index:: builtin: bytes diff --git a/Include/cpython/object.h b/Include/cpython/object.h index fd4e77103f01b..75e55995b5741 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -348,6 +348,7 @@ static inline void _Py_Dealloc_inline(PyObject *op) } #define _Py_Dealloc(op) _Py_Dealloc_inline(op) +PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); /* Safely decref `op` and set `op` to `op2`. * diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index c233ba1351fe5..d178aa4ec2bd2 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -74,7 +74,7 @@ def test_varargs3_kw(self): self.assertRaisesRegex(TypeError, msg, bool, x=2) def test_varargs4_kw(self): - msg = r"^index\(\) takes no keyword arguments$" + msg = r"^list[.]index\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, [].index, x=2) def test_varargs5_kw(self): @@ -90,19 +90,19 @@ def test_varargs7_kw(self): self.assertRaisesRegex(TypeError, msg, next, x=2) def test_varargs8_kw(self): - msg = r"^pack\(\) takes no keyword arguments$" + msg = r"^_struct[.]pack\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, struct.pack, x=2) def test_varargs9_kw(self): - msg = r"^pack_into\(\) takes no keyword arguments$" + msg = r"^_struct[.]pack_into\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2) def test_varargs10_kw(self): - msg = r"^index\(\) takes no keyword arguments$" + msg = r"^deque[.]index\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2) def test_varargs11_kw(self): - msg = r"^pack\(\) takes no keyword arguments$" + msg = r"^Struct[.]pack\(\) takes no keyword arguments$" self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2) def test_varargs12_kw(self): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 796e60a770479..d2e121820ea5f 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1967,7 +1967,7 @@ def test_methods_in_c(self): # different error messages. set_add = set.add - expected_errmsg = "descriptor 'add' of 'set' object needs an argument" + expected_errmsg = "unbound method set.add() needs an argument" with self.assertRaises(TypeError) as cm: set_add() diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index d9dcb709f7541..4edb6680e0f98 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -52,15 +52,15 @@ >>> f(1, 2, **{'a': -1, 'b': 5}, **{'a': 4, 'c': 6}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: test.test_extcall.f() got multiple values for keyword argument 'a' >>> f(1, 2, **{'a': -1, 'b': 5}, a=4, c=6) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: test.test_extcall.f() got multiple values for keyword argument 'a' >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: test.test_extcall.f() got multiple values for keyword argument 'a' >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7}) (1, 2, 3, 4, 5) {'a': 6, 'b': 7} >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9}) @@ -118,7 +118,7 @@ >>> g(*Nothing()) Traceback (most recent call last): ... - TypeError: g() argument after * must be an iterable, not Nothing + TypeError: test.test_extcall.g() argument after * must be an iterable, not Nothing >>> class Nothing: ... def __len__(self): return 5 @@ -127,7 +127,7 @@ >>> g(*Nothing()) Traceback (most recent call last): ... - TypeError: g() argument after * must be an iterable, not Nothing + TypeError: test.test_extcall.g() argument after * must be an iterable, not Nothing >>> class Nothing(): ... def __len__(self): return 5 @@ -247,17 +247,17 @@ >>> h(*h) Traceback (most recent call last): ... - TypeError: h() argument after * must be an iterable, not function + TypeError: test.test_extcall.h() argument after * must be an iterable, not function >>> h(1, *h) Traceback (most recent call last): ... - TypeError: h() argument after * must be an iterable, not function + TypeError: test.test_extcall.h() argument after * must be an iterable, not function >>> h(*[1], *h) Traceback (most recent call last): ... - TypeError: h() argument after * must be an iterable, not function + TypeError: test.test_extcall.h() argument after * must be an iterable, not function >>> dir(*h) Traceback (most recent call last): @@ -268,38 +268,38 @@ >>> nothing(*h) Traceback (most recent call last): ... - TypeError: NoneType object argument after * must be an iterable, \ + TypeError: None argument after * must be an iterable, \ not function >>> h(**h) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: test.test_extcall.h() argument after ** must be a mapping, not function >>> h(**[]) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not list + TypeError: test.test_extcall.h() argument after ** must be a mapping, not list >>> h(a=1, **h) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: test.test_extcall.h() argument after ** must be a mapping, not function >>> h(a=1, **[]) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not list + TypeError: test.test_extcall.h() argument after ** must be a mapping, not list >>> h(**{'a': 1}, **h) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not function + TypeError: test.test_extcall.h() argument after ** must be a mapping, not function >>> h(**{'a': 1}, **[]) Traceback (most recent call last): ... - TypeError: h() argument after ** must be a mapping, not list + TypeError: test.test_extcall.h() argument after ** must be a mapping, not list >>> dir(**h) Traceback (most recent call last): @@ -309,7 +309,7 @@ >>> nothing(**h) Traceback (most recent call last): ... - TypeError: NoneType object argument after ** must be a mapping, \ + TypeError: None argument after ** must be a mapping, \ not function >>> dir(b=1, **{'b': 1}) @@ -351,17 +351,17 @@ >>> g(**MultiDict([('x', 1), ('x', 2)])) Traceback (most recent call last): ... - TypeError: g() got multiple values for keyword argument 'x' + TypeError: test.test_extcall.g() got multiple values for keyword argument 'x' >>> g(a=3, **MultiDict([('x', 1), ('x', 2)])) Traceback (most recent call last): ... - TypeError: g() got multiple values for keyword argument 'x' + TypeError: test.test_extcall.g() got multiple values for keyword argument 'x' >>> g(**MultiDict([('a', 3)]), **MultiDict([('x', 1), ('x', 2)])) Traceback (most recent call last): ... - TypeError: g() got multiple values for keyword argument 'x' + TypeError: test.test_extcall.g() got multiple values for keyword argument 'x' Another helper function diff --git a/Lib/test/test_unpack_ex.py b/Lib/test/test_unpack_ex.py index 87fea593c0201..46f70c2b98c70 100644 --- a/Lib/test/test_unpack_ex.py +++ b/Lib/test/test_unpack_ex.py @@ -236,27 +236,27 @@ >>> f(x=5, **{'x': 3}, y=2) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'x' + TypeError: test.test_unpack_ex.f() got multiple values for keyword argument 'x' >>> f(**{'x': 3}, x=5, y=2) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'x' + TypeError: test.test_unpack_ex.f() got multiple values for keyword argument 'x' >>> f(**{'x': 3}, **{'x': 5}, y=2) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'x' + TypeError: test.test_unpack_ex.f() got multiple values for keyword argument 'x' >>> f(x=5, **{'x': 3}, **{'x': 2}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'x' + TypeError: test.test_unpack_ex.f() got multiple values for keyword argument 'x' >>> f(**{1: 3}, **{1: 5}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument '1' + TypeError: test.test_unpack_ex.f() got multiple values for keyword argument '1' Unpacking non-sequence diff --git a/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst b/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst new file mode 100644 index 0000000000000..2a6efaaaeafae --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst @@ -0,0 +1,2 @@ +Add :c:func:`_PyObject_FunctionStr` to get a user-friendly string representation +of a function-like object. Patch by Jeroen Demeyer. diff --git a/Objects/descrobject.c b/Objects/descrobject.c index dbab4cd4da2c6..342b993e09039 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -231,45 +231,38 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) * * First, common helpers */ -static const char * -get_name(PyObject *func) { - assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); - return ((PyMethodDescrObject *)func)->d_method->ml_name; -} - -typedef void (*funcptr)(void); - static inline int method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { assert(!PyErr_Occurred()); - assert(PyObject_TypeCheck(func, &PyMethodDescr_Type)); if (nargs < 1) { - PyErr_Format(PyExc_TypeError, - "descriptor '%.200s' of '%.100s' " - "object needs an argument", - get_name(func), PyDescr_TYPE(func)->tp_name); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "unbound method %U needs an argument", funcstr); + Py_DECREF(funcstr); + } return -1; } PyObject *self = args[0]; - if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), - (PyObject *)PyDescr_TYPE(func))) - { - PyErr_Format(PyExc_TypeError, - "descriptor '%.200s' for '%.100s' objects " - "doesn't apply to a '%.100s' object", - get_name(func), PyDescr_TYPE(func)->tp_name, - Py_TYPE(self)->tp_name); + PyObject *dummy; + if (descr_check((PyDescrObject *)func, self, &dummy)) { return -1; } if (kwnames && PyTuple_GET_SIZE(kwnames)) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", get_name(func)); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes no keyword arguments", funcstr); + Py_DECREF(funcstr); + } return -1; } return 0; } +typedef void (*funcptr)(void); + static inline funcptr method_enter_call(PyThreadState *tstate, PyObject *func) { @@ -387,8 +380,12 @@ method_vectorcall_NOARGS( return NULL; } if (nargs != 1) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%zd given)", get_name(func), nargs-1); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes no arguments (%zd given)", funcstr, nargs-1); + Py_DECREF(funcstr); + } return NULL; } PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); @@ -410,9 +407,13 @@ method_vectorcall_O( return NULL; } if (nargs != 2) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%zd given)", - get_name(func), nargs-1); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyErr_Format(PyExc_TypeError, + "%U takes exactly one argument (%zd given)", + funcstr, nargs-1); + Py_DECREF(funcstr); + } return NULL; } PyCFunction meth = (PyCFunction)method_enter_call(tstate, func); diff --git a/Objects/methodobject.c b/Objects/methodobject.c index c780904d7f9aa..8f752c610ce4b 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -334,15 +334,6 @@ _PyCFunction_Fini(void) * * First, common helpers */ -static const char * -get_name(PyObject *func) -{ - assert(PyCFunction_Check(func)); - PyMethodDef *method = ((PyCFunctionObject *)func)->m_ml; - return method->ml_name; -} - -typedef void (*funcptr)(void); static inline int cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames) @@ -350,13 +341,19 @@ cfunction_check_kwargs(PyThreadState *tstate, PyObject *func, PyObject *kwnames) assert(!_PyErr_Occurred(tstate)); assert(PyCFunction_Check(func)); if (kwnames && PyTuple_GET_SIZE(kwnames)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s() takes no keyword arguments", get_name(func)); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U takes no keyword arguments", funcstr); + Py_DECREF(funcstr); + } return -1; } return 0; } +typedef void (*funcptr)(void); + static inline funcptr cfunction_enter_call(PyThreadState *tstate, PyObject *func) { @@ -412,9 +409,12 @@ cfunction_vectorcall_NOARGS( } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 0) { - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s() takes no arguments (%zd given)", - get_name(func), nargs); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U takes no arguments (%zd given)", funcstr, nargs); + Py_DECREF(funcstr); + } return NULL; } PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); @@ -436,9 +436,12 @@ cfunction_vectorcall_O( } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); if (nargs != 1) { - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s() takes exactly one argument (%zd given)", - get_name(func), nargs); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U takes exactly one argument (%zd given)", funcstr, nargs); + Py_DECREF(funcstr); + } return NULL; } PyCFunction meth = (PyCFunction)cfunction_enter_call(tstate, func); diff --git a/Objects/object.c b/Objects/object.c index 9536d467f5f2a..3e612825c2777 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -681,6 +681,64 @@ PyObject_Bytes(PyObject *v) return PyBytes_FromObject(v); } + +/* +def _PyObject_FunctionStr(x): + try: + qualname = x.__qualname__ + except AttributeError: + return str(x) + try: + mod = x.__module__ + if mod is not None and mod != 'builtins': + return f"{x.__module__}.{qualname}()" + except AttributeError: + pass + return qualname +*/ +PyObject * +_PyObject_FunctionStr(PyObject *x) +{ + _Py_IDENTIFIER(__module__); + _Py_IDENTIFIER(__qualname__); + _Py_IDENTIFIER(builtins); + assert(!PyErr_Occurred()); + PyObject *qualname; + int ret = _PyObject_LookupAttrId(x, &PyId___qualname__, &qualname); + if (qualname == NULL) { + if (ret < 0) { + return NULL; + } + return PyObject_Str(x); + } + PyObject *module; + PyObject *result = NULL; + ret = _PyObject_LookupAttrId(x, &PyId___module__, &module); + if (module != NULL && module != Py_None) { + PyObject *builtinsname = _PyUnicode_FromId(&PyId_builtins); + if (builtinsname == NULL) { + goto done; + } + ret = PyObject_RichCompareBool(module, builtinsname, Py_NE); + if (ret < 0) { + // error + goto done; + } + if (ret > 0) { + result = PyUnicode_FromFormat("%S.%S()", module, qualname); + goto done; + } + } + else if (ret < 0) { + goto done; + } + result = PyUnicode_FromFormat("%S()", qualname); +done: + Py_DECREF(qualname); + Py_XDECREF(module); + return result; +} + /* For Python 3.0.1 and later, the old three-way comparison has been completely removed in favour of rich comparisons. PyObject_Compare() and PyObject_Cmp() are gone, and the builtin cmp function no longer exists. diff --git a/Python/ceval.c b/Python/ceval.c index 9019c785080a3..4d8f1b913c530 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5351,12 +5351,17 @@ static int check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) { if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s%.200s argument after * " - "must be an iterable, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - args->ob_type->tp_name); + /* check_args_iterable() may be called with a live exception: + * clear it to prevent calling _PyObject_FunctionStr() with an + * exception set. */ + PyErr_Clear(); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "%U argument after * must be an iterable, not %.200s", + funcstr, Py_TYPE(args)->tp_name); + Py_DECREF(funcstr); + } return -1; } return 0; @@ -5372,24 +5377,30 @@ format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) * is not a mapping. */ if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - kwargs->ob_type->tp_name); + PyErr_Clear(); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + _PyErr_Format( + tstate, PyExc_TypeError, + "%U argument after ** must be a mapping, not %.200s", + funcstr, Py_TYPE(kwargs)->tp_name); + Py_DECREF(funcstr); + } } else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { PyObject *exc, *val, *tb; _PyErr_Fetch(tstate, &exc, &val, &tb); if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { - PyObject *key = PyTuple_GET_ITEM(val, 0); - _PyErr_Format(tstate, PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%S'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); + PyErr_Clear(); + PyObject *funcstr = _PyObject_FunctionStr(func); + if (funcstr != NULL) { + PyObject *key = PyTuple_GET_ITEM(val, 0); + _PyErr_Format( + tstate, PyExc_TypeError, + "%U got multiple values for keyword argument '%S'", + funcstr, key); + Py_DECREF(funcstr); + } Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); From tjreedy at udel.edu Tue Nov 5 15:17:06 2019 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 5 Nov 2019 15:17:06 -0500 Subject: [Python-checkins] Update interpreter.rst (GH-17059) In-Reply-To: <476rjK0cCHznWpL@mail.python.org> References: <476rjK0cCHznWpL@mail.python.org> Message-ID: <5c71c851-c73f-1cd6-2537-64cf751734c1@udel.edu> On 11/5/2019 8:53 AM, Victor Stinner wrote: > `, the :file:`python3.9` command will be available. If you have I know you did not write this part of the file, but 'python3.9' most likely should be 'python3.8' ;-). From webhook-mailer at python.org Tue Nov 5 18:29:43 2019 From: webhook-mailer at python.org (Zachary Ware) Date: Tue, 05 Nov 2019 23:29:43 -0000 Subject: [Python-checkins] bpo-38696: Fix usage example of HTTPStatus (GH-17066) Message-ID: https://github.com/python/cpython/commit/56698d57691af2272f695f8c17c835ed99545cde commit: 56698d57691af2272f695f8c17c835ed99545cde branch: master author: Ammar Askar committer: Zachary Ware date: 2019-11-05T17:29:33-06:00 summary: bpo-38696: Fix usage example of HTTPStatus (GH-17066) files: M Doc/library/http.rst diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 8df14578de1f1..0e3441cbcb718 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -38,7 +38,7 @@ associated messages through the :class:`http.HTTPStatus` enum: >>> HTTPStatus.OK == 200 True - >>> http.HTTPStatus.OK.value + >>> HTTPStatus.OK.value 200 >>> HTTPStatus.OK.phrase 'OK' From webhook-mailer at python.org Tue Nov 5 22:21:44 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 06 Nov 2019 03:21:44 -0000 Subject: [Python-checkins] bpo-38692: Add os.pidfd_open. (GH-17063) Message-ID: https://github.com/python/cpython/commit/6c4c45efaeb40f4f837570f57d90a0b3429c6ae9 commit: 6c4c45efaeb40f4f837570f57d90a0b3429c6ae9 branch: master author: Benjamin Peterson committer: GitHub date: 2019-11-05T19:21:29-08:00 summary: bpo-38692: Add os.pidfd_open. (GH-17063) files: A Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst M Doc/library/os.rst M Doc/whatsnew/3.9.rst M Lib/test/test_posix.py M Modules/clinic/posixmodule.c.h M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 8e9d9e6f034e3..9c907a7ee5911 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3539,6 +3539,19 @@ written in Python, such as a mail server's external command delivery program. .. availability:: Unix. +.. function:: pidfd_open(pid, flags=0) + + Return a file descriptor referring to the process *pid*. This descriptor can + be used to perform process management without races and signals. The *flags* + argument is provided for future extensions; no flag values are currently + defined. + + See the :manpage:`pidfd_open(2)` man page for more details. + + .. availability:: Linux 5.3+ + .. versionadded:: 3.9 + + .. function:: plock(op) Lock program segments into memory. The value of *op* (defined in diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 3cac9c5eedbc2..7e778058c8ded 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -150,6 +150,9 @@ os Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`. (Contributed by Dong-hee Na in :issue:`38493`.) +Exposed the Linux-specific :func:`os.pidfd_open` for process management with +file descriptors. (:issue:`38692`) + threading --------- diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 17e4ded2e2d69..98a39c3f04099 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1470,6 +1470,15 @@ def test_path_with_null_byte(self): open(fn, 'wb').close() self.assertRaises(ValueError, os.stat, fn_with_NUL) + @unittest.skipUnless(hasattr(os, "pidfd_open"), "pidfd_open unavailable") + def test_pidfd_open(self): + with self.assertRaises(OSError) as cm: + os.pidfd_open(-1) + if cm.exception.errno == errno.ENOSYS: + self.skipTest("system does not support pidfd_open") + self.assertEqual(cm.exception.errno, errno.EINVAL) + os.close(os.pidfd_open(os.getpid(), 0)) + class PosixGroupsTester(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst b/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst new file mode 100644 index 0000000000000..fd19c6f9eb52e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst @@ -0,0 +1 @@ +Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 3dada674fbab0..aa4756a620aae 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -3963,6 +3963,44 @@ os_wait(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(HAVE_WAIT) */ +#if (defined(__linux__) && defined(__NR_pidfd_open)) + +PyDoc_STRVAR(os_pidfd_open__doc__, +"pidfd_open($module, /, pid, flags=0)\n" +"--\n" +"\n" +"Return a file descriptor referring to the process *pid*.\n" +"\n" +"The descriptor can be used to perform process management without races and\n" +"signals."); + +#define OS_PIDFD_OPEN_METHODDEF \ + {"pidfd_open", (PyCFunction)(void(*)(void))os_pidfd_open, METH_FASTCALL|METH_KEYWORDS, os_pidfd_open__doc__}, + +static PyObject * +os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags); + +static PyObject * +os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"pid", "flags", NULL}; + static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; + pid_t pid; + unsigned int flags = 0; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &pid, _PyLong_UnsignedInt_Converter, &flags)) { + goto exit; + } + return_value = os_pidfd_open_impl(module, pid, flags); + +exit: + return return_value; +} + +#endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */ + #if (defined(HAVE_READLINK) || defined(MS_WINDOWS)) PyDoc_STRVAR(os_readlink__doc__, @@ -8480,6 +8518,10 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #define OS_WAIT_METHODDEF #endif /* !defined(OS_WAIT_METHODDEF) */ +#ifndef OS_PIDFD_OPEN_METHODDEF + #define OS_PIDFD_OPEN_METHODDEF +#endif /* !defined(OS_PIDFD_OPEN_METHODDEF) */ + #ifndef OS_READLINK_METHODDEF #define OS_READLINK_METHODDEF #endif /* !defined(OS_READLINK_METHODDEF) */ @@ -8731,4 +8773,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=c6e67d475eef00c4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=51ba5b9536420cea input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 6d837c6552f49..46cf7b2f55ac1 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7861,6 +7861,30 @@ os_wait_impl(PyObject *module) } #endif /* HAVE_WAIT */ +#if defined(__linux__) && defined(__NR_pidfd_open) +/*[clinic input] +os.pidfd_open + pid: pid_t + flags: unsigned_int = 0 + +Return a file descriptor referring to the process *pid*. + +The descriptor can be used to perform process management without races and +signals. +[clinic start generated code]*/ + +static PyObject * +os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags) +/*[clinic end generated code: output=5c7252698947dc41 input=c3fd99ce947ccfef]*/ +{ + int fd = syscall(__NR_pidfd_open, pid, flags); + if (fd < 0) { + return posix_error(); + } + return PyLong_FromLong(fd); +} +#endif + #if defined(HAVE_READLINK) || defined(MS_WINDOWS) /*[clinic input] @@ -13671,6 +13695,7 @@ static PyMethodDef posix_methods[] = { OS_WAIT4_METHODDEF OS_WAITID_METHODDEF OS_WAITPID_METHODDEF + OS_PIDFD_OPEN_METHODDEF OS_GETSID_METHODDEF OS_SETSID_METHODDEF OS_SETPGID_METHODDEF From webhook-mailer at python.org Wed Nov 6 00:58:39 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 06 Nov 2019 05:58:39 -0000 Subject: [Python-checkins] closes bpo-38713: Expose P_PIDFD in os if it's defined. (GH-17071) Message-ID: https://github.com/python/cpython/commit/5c0c325453a175350e3c18ebb10cc10c37f9595c commit: 5c0c325453a175350e3c18ebb10cc10c37f9595c branch: master author: Benjamin Peterson committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-05T21:58:31-08:00 summary: closes bpo-38713: Expose P_PIDFD in os if it's defined. (GH-17071) https://bugs.python.org/issue38713 files: A Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst M Doc/library/os.rst M Doc/whatsnew/3.9.rst M Modules/posixmodule.c M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 9c907a7ee5911..48bd6b95a9b39 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3921,7 +3921,8 @@ written in Python, such as a mail server's external command delivery program. .. function:: waitid(idtype, id, options) Wait for the completion of one or more child processes. - *idtype* can be :data:`P_PID`, :data:`P_PGID` or :data:`P_ALL`. + *idtype* can be :data:`P_PID`, :data:`P_PGID`, :data:`P_ALL`, or + :data:`P_PIDFD` on Linux. *id* specifies the pid to wait on. *options* is constructed from the ORing of one or more of :data:`WEXITED`, :data:`WSTOPPED` or :data:`WCONTINUED` and additionally may be ORed with @@ -3946,6 +3947,15 @@ written in Python, such as a mail server's external command delivery program. .. versionadded:: 3.3 +.. data:: P_PIDFD + + This is a Linux-specific *idtype* that indicates that *id* is a file + descriptor that refers to a process. + + .. availability:: Linux 5.4+ + + .. versionadded:: 3.9 + .. data:: WEXITED WSTOPPED WNOWAIT diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 7e778058c8ded..1cd21c6ab8f71 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -150,8 +150,9 @@ os Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`. (Contributed by Dong-hee Na in :issue:`38493`.) -Exposed the Linux-specific :func:`os.pidfd_open` for process management with -file descriptors. (:issue:`38692`) +Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and +:data:`os.P_PIDFD` (:issue:`38713`) for process management with file +descriptors. threading --------- diff --git a/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst b/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst new file mode 100644 index 0000000000000..a22719753d7f8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst @@ -0,0 +1,2 @@ +Add :data:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to +wait on a Linux process file descriptor. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 46cf7b2f55ac1..f7386300c5691 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -85,6 +85,9 @@ corresponding Unix manual entries for more information on calls."); #ifdef HAVE_SYS_WAIT_H #include /* For WNOHANG */ #endif +#ifdef HAVE_LINUX_WAIT_H +#include // For P_PIDFD +#endif #ifdef HAVE_SIGNAL_H #include @@ -14099,6 +14102,9 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, P_PID)) return -1; if (PyModule_AddIntMacro(m, P_PGID)) return -1; if (PyModule_AddIntMacro(m, P_ALL)) return -1; +#ifdef P_PIDFD + if (PyModule_AddIntMacro(m, P_PIDFD)) return -1; +#endif #endif #ifdef WEXITED if (PyModule_AddIntMacro(m, WEXITED)) return -1; diff --git a/configure b/configure index 50840ac152105..44f14c3c2cfe1 100755 --- a/configure +++ b/configure @@ -782,6 +782,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -895,6 +896,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1147,6 +1149,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1284,7 +1295,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1437,6 +1448,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -7917,7 +7929,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h +sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/configure.ac b/configure.ac index 20d8a5239f173..0b28dda44cdb8 100644 --- a/configure.ac +++ b/configure.ac @@ -2161,7 +2161,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h) +sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h) AC_HEADER_DIRENT AC_HEADER_MAJOR diff --git a/pyconfig.h.in b/pyconfig.h.in index 9595d7537de47..50af4c6fee43d 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -642,6 +642,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_VM_SOCKETS_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_WAIT_H + /* Define to 1 if you have the `lockf' function. */ #undef HAVE_LOCKF From webhook-mailer at python.org Wed Nov 6 01:10:11 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 06 Nov 2019 06:10:11 -0000 Subject: [Python-checkins] bpo-38684: haslib: fix build when Blake2 not enabled in OpenSSL (GH-17043) Message-ID: https://github.com/python/cpython/commit/7c20888e71304ecbf4bd3d595f364b7c691d30a0 commit: 7c20888e71304ecbf4bd3d595f364b7c691d30a0 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-05T22:10:05-08:00 summary: bpo-38684: haslib: fix build when Blake2 not enabled in OpenSSL (GH-17043) (cherry picked from commit 6552563b3d5061816720a5a6c7d4ffd6ba35b98b) Co-authored-by: Alexandru Ardelean files: A Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst M Modules/_hashopenssl.c diff --git a/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst b/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst new file mode 100644 index 0000000000000..c715ff9704127 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst @@ -0,0 +1 @@ +Fix _hashlib build when Blake2 is disabled, but OpenSSL supports it. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 1513e4e35edc6..3e5f9c3e0df6a 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -42,7 +42,7 @@ #define PY_OPENSSL_HAS_SHAKE 1 #endif -#ifdef NID_blake2b512 +#if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) #define PY_OPENSSL_HAS_BLAKE2 1 #endif From webhook-mailer at python.org Wed Nov 6 09:27:29 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 06 Nov 2019 14:27:29 -0000 Subject: [Python-checkins] bpo-38696: Fix usage example of HTTPStatus (GH-17066) Message-ID: https://github.com/python/cpython/commit/91f4b9282fe7cdc51c6612002d033da654f422c1 commit: 91f4b9282fe7cdc51c6612002d033da654f422c1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-06T06:27:17-08:00 summary: bpo-38696: Fix usage example of HTTPStatus (GH-17066) (cherry picked from commit 56698d57691af2272f695f8c17c835ed99545cde) Co-authored-by: Ammar Askar files: M Doc/library/http.rst diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 88d62cca3f904..0deeaf6246486 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -38,7 +38,7 @@ associated messages through the :class:`http.HTTPStatus` enum: >>> HTTPStatus.OK == 200 True - >>> http.HTTPStatus.OK.value + >>> HTTPStatus.OK.value 200 >>> HTTPStatus.OK.phrase 'OK' From webhook-mailer at python.org Wed Nov 6 09:27:29 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 06 Nov 2019 14:27:29 -0000 Subject: [Python-checkins] bpo-38696: Fix usage example of HTTPStatus (GH-17066) Message-ID: https://github.com/python/cpython/commit/30da387df193b9f05c2891ae601ae5a1d669a5c1 commit: 30da387df193b9f05c2891ae601ae5a1d669a5c1 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-06T06:27:09-08:00 summary: bpo-38696: Fix usage example of HTTPStatus (GH-17066) (cherry picked from commit 56698d57691af2272f695f8c17c835ed99545cde) Co-authored-by: Ammar Askar files: M Doc/library/http.rst diff --git a/Doc/library/http.rst b/Doc/library/http.rst index 8df14578de1f1..0e3441cbcb718 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -38,7 +38,7 @@ associated messages through the :class:`http.HTTPStatus` enum: >>> HTTPStatus.OK == 200 True - >>> http.HTTPStatus.OK.value + >>> HTTPStatus.OK.value 200 >>> HTTPStatus.OK.phrase 'OK' From webhook-mailer at python.org Wed Nov 6 10:40:14 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Wed, 06 Nov 2019 15:40:14 -0000 Subject: [Python-checkins] bpo-16575: Fix refleak on passing unions in ctypes (GH-17064) Message-ID: https://github.com/python/cpython/commit/484edbf9bf1a9e6bae0fcb10a0c165b89ea79295 commit: 484edbf9bf1a9e6bae0fcb10a0c165b89ea79295 branch: 3.7 author: Ammar Askar committer: Vinay Sajip date: 2019-11-06T15:40:06Z summary: bpo-16575: Fix refleak on passing unions in ctypes (GH-17064) The master and 3.8 versions of the previous change work as expected because we perform the lookup for the `from_param` after the union check. However, in 3.7, this lookup happens before the union validation and so we must decrease the reference for `cnv` before returning. files: M Modules/_ctypes/_ctypes.c diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index d2ce1b074348d..0e209c33a80af 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2285,6 +2285,7 @@ converters_from_argtypes(PyObject *ob) if (stgdict->flags & TYPEFLAG_HASUNION) { Py_DECREF(converters); Py_DECREF(ob); + Py_DECREF(cnv); if (!PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "item %zd in _argtypes_ passes a union by " From webhook-mailer at python.org Wed Nov 6 16:22:03 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Wed, 06 Nov 2019 21:22:03 -0000 Subject: [Python-checkins] bpo-38716: stop rotating handlers from setting inherited namer and rotator to None (GH-17072) Message-ID: https://github.com/python/cpython/commit/519cb8772a9745b1c7d8218cabcd2f96ceda4d62 commit: 519cb8772a9745b1c7d8218cabcd2f96ceda4d62 branch: master author: l0rb committer: Vinay Sajip date: 2019-11-06T21:21:40Z summary: bpo-38716: stop rotating handlers from setting inherited namer and rotator to None (GH-17072) files: A Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst M Lib/logging/handlers.py M Lib/test/test_logging.py diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 5641fee573556..c1aec9880d72a 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -48,6 +48,9 @@ class BaseRotatingHandler(logging.FileHandler): Not meant to be instantiated directly. Instead, use RotatingFileHandler or TimedRotatingFileHandler. """ + namer = None + rotator = None + def __init__(self, filename, mode, encoding=None, delay=False, errors=None): """ Use the specified filename for streamed logging @@ -58,8 +61,6 @@ def __init__(self, filename, mode, encoding=None, delay=False, errors=None): self.mode = mode self.encoding = encoding self.errors = errors - self.namer = None - self.rotator = None def emit(self, record): """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 53b5bfc93f33e..6de8803081e51 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -5030,6 +5030,25 @@ def namer(name): self.assertFalse(os.path.exists(namer(self.fn + ".3"))) rh.close() + def test_namer_rotator_inheritance(self): + class HandlerWithNamerAndRotator(logging.handlers.RotatingFileHandler): + def namer(self, name): + return name + ".test" + + def rotator(self, source, dest): + if os.path.exists(source): + os.rename(source, dest + ".rotated") + + rh = HandlerWithNamerAndRotator( + self.fn, backupCount=2, maxBytes=1) + self.assertEqual(rh.namer(self.fn), self.fn + ".test") + rh.emit(self.next_rec()) + self.assertLogFile(self.fn) + rh.emit(self.next_rec()) + self.assertLogFile(rh.namer(self.fn + ".1") + ".rotated") + self.assertFalse(os.path.exists(rh.namer(self.fn + ".1"))) + rh.close() + @support.requires_zlib def test_rotator(self): def namer(name): diff --git a/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst b/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst new file mode 100644 index 0000000000000..906eb6b6cd60a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst @@ -0,0 +1 @@ +logging: change RotatingHandler namer and rotator to class-level attributes. This stops __init__ from setting them to None in the case where a subclass defines them with eponymous methods. From webhook-mailer at python.org Thu Nov 7 00:10:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 07 Nov 2019 05:10:14 -0000 Subject: [Python-checkins] bpo-37731: Reorder includes in xmltok.c to avoid redefinition of _POSIX_C_SOURCE (GH-16733) Message-ID: https://github.com/python/cpython/commit/30114c7119a9ae0e610d6974f57f22d8d05ed50d commit: 30114c7119a9ae0e610d6974f57f22d8d05ed50d branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-06T21:10:05-08:00 summary: bpo-37731: Reorder includes in xmltok.c to avoid redefinition of _POSIX_C_SOURCE (GH-16733) (cherry picked from commit 8177404d520e81f16324a900f093adf3856d33f8) Co-authored-by: Pablo Galindo files: M Modules/expat/xmltok.c diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 11e9d1ccdad42..54cfedb85c28c 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -30,6 +30,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#ifdef _WIN32 +# include "winconfig.h" +#else +# ifdef HAVE_EXPAT_CONFIG_H +# include +# endif +#endif /* ndef _WIN32 */ + #include #include /* memcpy */ @@ -42,14 +50,6 @@ # include #endif -#ifdef _WIN32 -# include "winconfig.h" -#else -# ifdef HAVE_EXPAT_CONFIG_H -# include -# endif -#endif /* ndef _WIN32 */ - #include "expat_external.h" #include "internal.h" #include "xmltok.h" From webhook-mailer at python.org Thu Nov 7 00:29:53 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Thu, 07 Nov 2019 05:29:53 -0000 Subject: [Python-checkins] bpo-37731: Squish another _POSIX_C_SOURCE redefinition problem in expat. (GH-17077) Message-ID: https://github.com/python/cpython/commit/089e5f52a34377193a9e6c03088114b14c8507af commit: 089e5f52a34377193a9e6c03088114b14c8507af branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2019-11-06T21:29:43-08:00 summary: bpo-37731: Squish another _POSIX_C_SOURCE redefinition problem in expat. (GH-17077) files: M Modules/expat/xmlparse.c diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index e740f0e19c7d4..09ccacb5aae59 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -39,6 +39,12 @@ # define _CRT_RAND_S #endif +#ifdef _WIN32 +# include "winconfig.h" +#elif defined(HAVE_EXPAT_CONFIG_H) +# include +#endif /* ndef _WIN32 */ + #include #include /* memset(), memcpy() */ #include @@ -58,12 +64,6 @@ #define XML_BUILDING_EXPAT 1 -#ifdef _WIN32 -# include "winconfig.h" -#elif defined(HAVE_EXPAT_CONFIG_H) -# include -#endif /* ndef _WIN32 */ - #include "ascii.h" #include "expat.h" #include "siphash.h" From webhook-mailer at python.org Thu Nov 7 00:50:52 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Thu, 07 Nov 2019 05:50:52 -0000 Subject: [Python-checkins] bpo-38382: Document the early-out behavior for a zero (GH-17037) Message-ID: https://github.com/python/cpython/commit/7f460494d2309ace004a400bae8fc59134dc325c commit: 7f460494d2309ace004a400bae8fc59134dc325c branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-06T21:50:44-08:00 summary: bpo-38382: Document the early-out behavior for a zero (GH-17037) files: M Doc/library/statistics.rst diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index a702b2463c39b..00c0b539edce9 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -164,7 +164,8 @@ However, for reading convenience, most of the examples show sorted sequences. The harmonic mean, sometimes called the subcontrary mean, is the reciprocal of the arithmetic :func:`mean` of the reciprocals of the data. For example, the harmonic mean of three values *a*, *b* and *c* - will be equivalent to ``3/(1/a + 1/b + 1/c)``. + will be equivalent to ``3/(1/a + 1/b + 1/c)``. If one of the values + is zero, the result will be zero. The harmonic mean is a type of average, a measure of the central location of the data. It is often appropriate when averaging @@ -190,6 +191,10 @@ However, for reading convenience, most of the examples show sorted sequences. :exc:`StatisticsError` is raised if *data* is empty, or any element is less than zero. + The current algorithm has an early-out when it encounters a zero + in the input. This means that the subsequent inputs are not tested + for validity. (This behavior may change in the future.) + .. versionadded:: 3.6 From webhook-mailer at python.org Thu Nov 7 00:58:17 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Thu, 07 Nov 2019 05:58:17 -0000 Subject: [Python-checkins] bpo-38382: Document the early-out behavior for a zero (GH-17037) (GH-17078) Message-ID: https://github.com/python/cpython/commit/6b66dc387935df432cdbc01397ddef534a84ade9 commit: 6b66dc387935df432cdbc01397ddef534a84ade9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-06T21:58:11-08:00 summary: bpo-38382: Document the early-out behavior for a zero (GH-17037) (GH-17078) (cherry picked from commit 7f460494d2309ace004a400bae8fc59134dc325c) Co-authored-by: Raymond Hettinger files: M Doc/library/statistics.rst diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index a702b2463c39b..00c0b539edce9 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -164,7 +164,8 @@ However, for reading convenience, most of the examples show sorted sequences. The harmonic mean, sometimes called the subcontrary mean, is the reciprocal of the arithmetic :func:`mean` of the reciprocals of the data. For example, the harmonic mean of three values *a*, *b* and *c* - will be equivalent to ``3/(1/a + 1/b + 1/c)``. + will be equivalent to ``3/(1/a + 1/b + 1/c)``. If one of the values + is zero, the result will be zero. The harmonic mean is a type of average, a measure of the central location of the data. It is often appropriate when averaging @@ -190,6 +191,10 @@ However, for reading convenience, most of the examples show sorted sequences. :exc:`StatisticsError` is raised if *data* is empty, or any element is less than zero. + The current algorithm has an early-out when it encounters a zero + in the input. This means that the subsequent inputs are not tested + for validity. (This behavior may change in the future.) + .. versionadded:: 3.6 From webhook-mailer at python.org Thu Nov 7 05:09:19 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Thu, 07 Nov 2019 10:09:19 -0000 Subject: [Python-checkins] bpo-36876: Moved Parser/listnode.c statics to interpreter state. (GH-16328) Message-ID: https://github.com/python/cpython/commit/9def81aa52adc3cc89554156e40742cf17312825 commit: 9def81aa52adc3cc89554156e40742cf17312825 branch: master author: Vinay Sajip committer: GitHub date: 2019-11-07T10:08:58Z summary: bpo-36876: Moved Parser/listnode.c statics to interpreter state. (GH-16328) files: M Include/internal/pycore_pystate.h M Parser/listnode.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 91003dbead054..eb44ae93fc4c4 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -125,6 +125,15 @@ struct _is { struct _warnings_runtime_state warnings; PyObject *audit_hooks; +/* + * See bpo-36876: miscellaneous ad hoc statics have been moved here. + */ + struct { + struct { + int level; + int atbol; + } listnode; + } parser; }; PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T); diff --git a/Parser/listnode.c b/Parser/listnode.c index 8f1a1163b63d5..d431ae537e3b4 100644 --- a/Parser/listnode.c +++ b/Parser/listnode.c @@ -2,6 +2,7 @@ /* List a node on a file */ #include "Python.h" +#include "pycore_pystate.h" #include "token.h" #include "node.h" @@ -15,19 +16,21 @@ PyNode_ListTree(node *n) listnode(stdout, n); } -static int level, atbol; - static void listnode(FILE *fp, node *n) { - level = 0; - atbol = 1; + PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); + + interp->parser.listnode.level = 0; + interp->parser.listnode.atbol = 1; list1node(fp, n); } static void list1node(FILE *fp, node *n) { + PyInterpreterState *interp; + if (n == NULL) return; if (ISNONTERMINAL(TYPE(n))) { @@ -36,25 +39,26 @@ list1node(FILE *fp, node *n) list1node(fp, CHILD(n, i)); } else if (ISTERMINAL(TYPE(n))) { + interp = _PyInterpreterState_GET_UNSAFE(); switch (TYPE(n)) { case INDENT: - ++level; + interp->parser.listnode.level++; break; case DEDENT: - --level; + interp->parser.listnode.level--; break; default: - if (atbol) { + if (interp->parser.listnode.atbol) { int i; - for (i = 0; i < level; ++i) + for (i = 0; i < interp->parser.listnode.level; ++i) fprintf(fp, "\t"); - atbol = 0; + interp->parser.listnode.atbol = 0; } if (TYPE(n) == NEWLINE) { if (STR(n) != NULL) fprintf(fp, "%s", STR(n)); fprintf(fp, "\n"); - atbol = 1; + interp->parser.listnode.atbol = 1; } else fprintf(fp, "%s ", STR(n)); From webhook-mailer at python.org Thu Nov 7 05:13:40 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Thu, 07 Nov 2019 10:13:40 -0000 Subject: [Python-checkins] update a deprecated assert in logging tests (GH-17079) Message-ID: https://github.com/python/cpython/commit/991b02dc871e101e98edece37d8a570f6a39d79f commit: 991b02dc871e101e98edece37d8a570f6a39d79f branch: master author: l0rb committer: Vinay Sajip date: 2019-11-07T10:13:36Z summary: update a deprecated assert in logging tests (GH-17079) files: M Lib/test/test_logging.py diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 6de8803081e51..c47ad4ac75206 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1613,7 +1613,7 @@ def test_config_set_handler_names(self): format=%(levelname)s ++ %(message)s """ self.apply_config(test_config) - self.assertEquals(logging.getLogger().handlers[0].name, 'hand1') + self.assertEqual(logging.getLogger().handlers[0].name, 'hand1') def test_defaults_do_no_interpolation(self): """bpo-33802 defaults should not get interpolated""" From webhook-mailer at python.org Thu Nov 7 06:42:22 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 07 Nov 2019 11:42:22 -0000 Subject: [Python-checkins] bpo-38733: PyErr_Occurred() caller must hold the GIL (GH-17080) Message-ID: https://github.com/python/cpython/commit/d12d0e7c0fe2b49c40ac4d66365147c619d6c475 commit: d12d0e7c0fe2b49c40ac4d66365147c619d6c475 branch: master author: Victor Stinner committer: GitHub date: 2019-11-07T12:42:07+01:00 summary: bpo-38733: PyErr_Occurred() caller must hold the GIL (GH-17080) bpo-3605, bpo-38733: Optimize _PyErr_Occurred(): remove "tstate == NULL" test. Py_FatalError() no longer calls PyErr_Occurred() if called without holding the GIL. So PyErr_Occurred() no longer has to support tstate==NULL case. _Py_CheckFunctionResult(): use directly _PyErr_Occurred() to avoid explicit "!= NULL" test. files: M Doc/c-api/exceptions.rst M Include/internal/pycore_pyerrors.h M Objects/call.c M Objects/obmalloc.c M Python/errors.c diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index a042c6eee0a29..cd6df00aeb5cd 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -374,6 +374,8 @@ Querying the error indicator own a reference to the return value, so you do not need to :c:func:`Py_DECREF` it. + The caller must hold the GIL. + .. note:: Do not compare the return value to a specific exception; use diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index edbfdfa597e1f..f3aa3e8b98abe 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -10,7 +10,8 @@ extern "C" { static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) { - return tstate == NULL ? NULL : tstate->curexc_type; + assert(tstate != NULL); + return tstate->curexc_type; } diff --git a/Objects/call.c b/Objects/call.c index 0d5c41295c29c..a1d0b332cefcc 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -30,12 +30,10 @@ PyObject* _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, PyObject *result, const char *where) { - int err_occurred = (_PyErr_Occurred(tstate) != NULL); - assert((callable != NULL) ^ (where != NULL)); if (result == NULL) { - if (!err_occurred) { + if (!_PyErr_Occurred(tstate)) { if (callable) _PyErr_Format(tstate, PyExc_SystemError, "%R returned NULL without setting an error", @@ -52,7 +50,7 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, } } else { - if (err_occurred) { + if (_PyErr_Occurred(tstate)) { Py_DECREF(result); if (callable) { diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 50701dbd38454..722e91e3db440 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -2313,12 +2313,13 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) return data; } -static void +static inline void _PyMem_DebugCheckGIL(void) { - if (!PyGILState_Check()) + if (!PyGILState_Check()) { Py_FatalError("Python memory allocator called " "without holding the GIL"); + } } static void * diff --git a/Python/errors.c b/Python/errors.c index 9658afeb9f773..1783084c336b1 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -218,6 +218,9 @@ PyErr_SetString(PyObject *exception, const char *string) PyObject* _Py_HOT_FUNCTION PyErr_Occurred(void) { + /* The caller must hold the GIL. */ + assert(PyGILState_Check()); + PyThreadState *tstate = _PyThreadState_GET(); return _PyErr_Occurred(tstate); } From webhook-mailer at python.org Thu Nov 7 10:06:36 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Thu, 07 Nov 2019 15:06:36 -0000 Subject: [Python-checkins] [2.7] bpo-38730: Fix -Wstringop-truncation warnings. (GH-17075) Message-ID: https://github.com/python/cpython/commit/f32bcf8c27f3681407707bbb029323eb340d3c4b commit: f32bcf8c27f3681407707bbb029323eb340d3c4b branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2019-11-07T07:06:28-08:00 summary: [2.7] bpo-38730: Fix -Wstringop-truncation warnings. (GH-17075) files: A Misc/NEWS.d/next/Build/2019-11-06-20-53-54.bpo-38730.UQsW_r.rst M Modules/getpath.c M Modules/parsermodule.c M Modules/readline.c M Modules/signalmodule.c M Modules/zipimport.c M Objects/structseq.c M Python/compile.c diff --git a/Misc/NEWS.d/next/Build/2019-11-06-20-53-54.bpo-38730.UQsW_r.rst b/Misc/NEWS.d/next/Build/2019-11-06-20-53-54.bpo-38730.UQsW_r.rst new file mode 100644 index 0000000000000..08e4e0471387a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-06-20-53-54.bpo-38730.UQsW_r.rst @@ -0,0 +1 @@ +Fix problems identified by GCC's ``-Wstringop-truncation`` warning. diff --git a/Modules/getpath.c b/Modules/getpath.c index c42ce31178593..092ccc712f9d0 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -486,7 +486,7 @@ calculate_path(void) if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ - strncpy(argv0_path, tmpbuffer, MAXPATHLEN); + strncpy(argv0_path, tmpbuffer, MAXPATHLEN + 1); else { /* Interpret relative to progpath */ reduce(argv0_path); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index fcc618d5d90a6..759f0ff4f6f85 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -1055,14 +1055,15 @@ validate_numnodes(node *n, int num, const char *const name) static int validate_terminal(node *terminal, int type, char *string) { - int res = (validate_ntype(terminal, type) - && ((string == 0) || (strcmp(string, STR(terminal)) == 0))); - - if (!res && !PyErr_Occurred()) { + if (!validate_ntype(terminal, type)) { + return 0; + } + if (string != NULL && strcmp(string, STR(terminal)) != 0) { PyErr_Format(parser_error, "Illegal terminal: expected \"%s\"", string); + return 0; } - return (res); + return 1; } diff --git a/Modules/readline.c b/Modules/readline.c index 02621358238ea..64bb19ae3fa37 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1180,7 +1180,7 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) q = p; p = PyMem_Malloc(n+2); if (p != NULL) { - strncpy(p, q, n); + memcpy(p, q, n); p[n] = '\n'; p[n+1] = '\0'; } diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8628f7a8005ff..88b471193214d 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -173,8 +173,10 @@ trip_signal(int sig_num) cleared in PyErr_CheckSignals() before .tripped. */ is_tripped = 1; Py_AddPendingCall(checksignals_witharg, NULL); - if (wakeup_fd != -1) - write(wakeup_fd, "\0", 1); + if (wakeup_fd != -1) { + int rc = write(wakeup_fd, "\0", 1); + (void)rc; + } } static void diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 1691773ec10f2..8ec2475571ca6 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -714,8 +714,8 @@ read_directory(const char *archive) unsigned int count, i; unsigned char buffer[46]; size_t length; - char path[MAXPATHLEN + 5]; - char name[MAXPATHLEN + 5]; + char name[MAXPATHLEN + 1]; + char path[2*MAXPATHLEN + 2]; /* archive + SEP + name + '\0' */ const char *errmsg = NULL; if (strlen(archive) > MAXPATHLEN) { @@ -838,7 +838,7 @@ read_directory(const char *archive) } } - strncpy(path + length + 1, name, MAXPATHLEN - length - 1); + memcpy(path + length + 1, name, name_size + 1); t = Py_BuildValue("sHIIkHHI", path, compress, data_size, file_size, file_offset, time, date, crc); diff --git a/Objects/structseq.c b/Objects/structseq.c index aee95286f78bc..14b51688a65a2 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -252,10 +252,7 @@ structseq_repr(PyStructSequence *obj) } /* "typename(", limited to TYPE_MAXSIZE */ - len = strlen(typ->tp_name) > TYPE_MAXSIZE ? TYPE_MAXSIZE : - strlen(typ->tp_name); - strncpy(pbuf, typ->tp_name, len); - pbuf += len; + pbuf = stpncpy(pbuf, typ->tp_name, TYPE_MAXSIZE); *pbuf++ = '('; for (i=0; i < VISIBLE_SIZE(obj); i++) { diff --git a/Python/compile.c b/Python/compile.c index 4fe69e12bf848..6386a40731ed6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -221,7 +221,7 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) } plen = strlen(p); - if (plen + nlen >= PY_SSIZE_T_MAX - 1) { + if (nlen >= PY_SSIZE_T_MAX - 1 - plen) { PyErr_SetString(PyExc_OverflowError, "private identifier too large to be mangled"); return NULL; @@ -233,7 +233,7 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident) /* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */ buffer = PyString_AS_STRING(ident); buffer[0] = '_'; - strncpy(buffer+1, p, plen); + memcpy(buffer+1, p, plen); strcpy(buffer+1+plen, name); return ident; } From webhook-mailer at python.org Thu Nov 7 10:27:13 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Thu, 07 Nov 2019 15:27:13 -0000 Subject: [Python-checkins] bpo-38730: Remove usage of stpncpy as it's not supported on MSVC 2008. (GH-17081) Message-ID: https://github.com/python/cpython/commit/9f94e52e8d38092520a3bfb1bf1ef9cbb0836584 commit: 9f94e52e8d38092520a3bfb1bf1ef9cbb0836584 branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2019-11-07T07:27:03-08:00 summary: bpo-38730: Remove usage of stpncpy as it's not supported on MSVC 2008. (GH-17081) files: M Objects/structseq.c diff --git a/Objects/structseq.c b/Objects/structseq.c index 14b51688a65a2..82df926f28604 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -252,7 +252,12 @@ structseq_repr(PyStructSequence *obj) } /* "typename(", limited to TYPE_MAXSIZE */ - pbuf = stpncpy(pbuf, typ->tp_name, TYPE_MAXSIZE); + len = strlen(typ->tp_name); + if (len > TYPE_MAXSIZE) { + len = TYPE_MAXSIZE; + } + pbuf = memcpy(pbuf, typ->tp_name, len); + pbuf += len; *pbuf++ = '('; for (i=0; i < VISIBLE_SIZE(obj); i++) { From webhook-mailer at python.org Thu Nov 7 10:59:11 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Thu, 07 Nov 2019 15:59:11 -0000 Subject: [Python-checkins] bpo-38613: Optimize set operations of dict keys. (GH-16961) Message-ID: https://github.com/python/cpython/commit/6cbc84fb99acb33dd659d7adb29a20adbe62b74a commit: 6cbc84fb99acb33dd659d7adb29a20adbe62b74a branch: master author: Inada Naoki committer: GitHub date: 2019-11-08T00:59:04+09:00 summary: bpo-38613: Optimize set operations of dict keys. (GH-16961) files: A Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC.rst M Objects/dictobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC.rst new file mode 100644 index 0000000000000..c001db6679831 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC.rst @@ -0,0 +1,3 @@ +Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of +``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but +they are almost same performance for now. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index d909f220a984b..4afa19c8a0a90 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4162,17 +4162,34 @@ static PySequenceMethods dictkeys_as_sequence = { (objobjproc)dictkeys_contains, /* sq_contains */ }; +// Create an set object from dictviews object. +// Returns a new reference. +// This utility function is used by set operations. static PyObject* -dictviews_sub(PyObject* self, PyObject *other) +dictviews_to_set(PyObject *self) { - PyObject *result = PySet_New(self); - PyObject *tmp; - _Py_IDENTIFIER(difference_update); + PyObject *left = self; + if (PyDictKeys_Check(self)) { + // PySet_New() has fast path for the dict object. + PyObject *dict = (PyObject *)((_PyDictViewObject *)self)->dv_dict; + if (PyDict_CheckExact(dict)) { + left = dict; + } + } + return PySet_New(left); +} - if (result == NULL) +static PyObject* +dictviews_sub(PyObject *self, PyObject *other) +{ + PyObject *result = dictviews_to_set(self); + if (result == NULL) { return NULL; + } - tmp = _PyObject_CallMethodIdOneArg(result, &PyId_difference_update, other); + _Py_IDENTIFIER(difference_update); + PyObject *tmp = _PyObject_CallMethodIdOneArg( + result, &PyId_difference_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -4273,34 +4290,29 @@ _PyDictView_Intersect(PyObject* self, PyObject *other) static PyObject* dictviews_or(PyObject* self, PyObject *other) { - PyObject *result = PySet_New(self); - PyObject *tmp; - _Py_IDENTIFIER(update); - - if (result == NULL) + PyObject *result = dictviews_to_set(self); + if (result == NULL) { return NULL; + } - tmp = _PyObject_CallMethodIdOneArg(result, &PyId_update, other); - if (tmp == NULL) { + if (_PySet_Update(result, other) < 0) { Py_DECREF(result); return NULL; } - - Py_DECREF(tmp); return result; } static PyObject* dictviews_xor(PyObject* self, PyObject *other) { - PyObject *result = PySet_New(self); - PyObject *tmp; - _Py_IDENTIFIER(symmetric_difference_update); - - if (result == NULL) + PyObject *result = dictviews_to_set(self); + if (result == NULL) { return NULL; + } - tmp = _PyObject_CallMethodIdOneArg(result, &PyId_symmetric_difference_update, other); + _Py_IDENTIFIER(symmetric_difference_update); + PyObject *tmp = _PyObject_CallMethodIdOneArg( + result, &PyId_symmetric_difference_update, other); if (tmp == NULL) { Py_DECREF(result); return NULL; From webhook-mailer at python.org Thu Nov 7 15:31:46 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 07 Nov 2019 20:31:46 -0000 Subject: [Python-checkins] bpo-22367: Add tests for fcntl.lockf(). (GH-17010) Message-ID: https://github.com/python/cpython/commit/befa032d8869e0fab4732d910f3887642879d644 commit: befa032d8869e0fab4732d910f3887642879d644 branch: master author: Dong-hee Na committer: Serhiy Storchaka date: 2019-11-07T22:31:41+02:00 summary: bpo-22367: Add tests for fcntl.lockf(). (GH-17010) files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index a2b5997067539..9d1be28c6d399 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -5,6 +5,7 @@ import struct import sys import unittest +from multiprocessing import Process from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, cpython_only) @@ -12,7 +13,6 @@ fcntl = import_module('fcntl') -# TODO - Write tests for flock() and lockf(). def get_lockdata(): try: @@ -138,6 +138,33 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + def test_lockf_exclusive(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_EX | fcntl.LOCK_NB + def try_lockf_on_other_process(): + self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + + def test_lockf_share(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_SH | fcntl.LOCK_NB + def try_lockf_on_other_process(): + fcntl.lockf(self.f, cmd) + fcntl.lockf(self.f, fcntl.LOCK_UN) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + @cpython_only def test_flock_overflow(self): import _testcapi From webhook-mailer at python.org Fri Nov 8 04:05:26 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 08 Nov 2019 09:05:26 -0000 Subject: [Python-checkins] bpo-38644: Add _PyObject_VectorcallTstate() (GH-17052) Message-ID: https://github.com/python/cpython/commit/7e433733175e76627d46ed9bdab543860cd1452d commit: 7e433733175e76627d46ed9bdab543860cd1452d branch: master author: Victor Stinner committer: GitHub date: 2019-11-08T10:05:17+01:00 summary: bpo-38644: Add _PyObject_VectorcallTstate() (GH-17052) * Add _PyObject_VectorcallTstate() function: similar to _PyObject_Vectorcall(), but with tstate parameter * Add tstate parameter to _PyObject_MakeTpCall() files: M Include/cpython/abstract.h M Modules/_functoolsmodule.c M Objects/call.c M Objects/classobject.c M Objects/typeobject.c M Python/context.c diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index be37e1971a814..fef538e63e042 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -49,6 +49,7 @@ PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( or _PyObject_FastCallDict() (both forms are supported), except that nargs is plainly the number of arguments without flags. */ PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( + PyThreadState *tstate, PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords); @@ -95,22 +96,31 @@ _PyVectorcall_Function(PyObject *callable) Return the result on success. Raise an exception and return NULL on error. */ static inline PyObject * -_PyObject_Vectorcall(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames) +_PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) { assert(kwnames == NULL || PyTuple_Check(kwnames)); assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); - PyThreadState *tstate = PyThreadState_GET(); vectorcallfunc func = _PyVectorcall_Function(callable); if (func == NULL) { Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall(callable, args, nargs, kwnames); + return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); } PyObject *res = func(callable, args, nargsf, kwnames); return _Py_CheckFunctionResult(tstate, callable, res, NULL); } +static inline PyObject * +_PyObject_Vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, callable, + args, nargsf, kwnames); +} + /* Same as _PyObject_Vectorcall except that keyword arguments are passed as dict, which may be NULL if there are no keyword arguments. */ PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 17d49ac5b342d..987087b1ac97b 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -132,21 +132,25 @@ partial_dealloc(partialobject *pto) * if we would need to do that, we stop using vectorcall and fall back * to using partial_call() instead. */ _Py_NO_INLINE static PyObject * -partial_vectorcall_fallback(partialobject *pto, PyObject *const *args, - size_t nargsf, PyObject *kwnames) +partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) { pto->vectorcall = NULL; Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall((PyObject *)pto, args, nargs, kwnames); + return _PyObject_MakeTpCall(tstate, (PyObject *)pto, + args, nargs, kwnames); } static PyObject * partial_vectorcall(partialobject *pto, PyObject *const *args, size_t nargsf, PyObject *kwnames) { + PyThreadState *tstate = _PyThreadState_GET(); + /* pto->kw is mutable, so need to check every time */ if (PyDict_GET_SIZE(pto->kw)) { - return partial_vectorcall_fallback(pto, args, nargsf, kwnames); + return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); } Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); @@ -160,7 +164,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, /* Fast path if we're called without arguments */ if (nargs_total == 0) { - return _PyObject_Vectorcall(pto->fn, pto_args, pto_nargs, NULL); + return _PyObject_VectorcallTstate(tstate, pto->fn, + pto_args, pto_nargs, NULL); } /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single @@ -169,7 +174,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, PyObject **newargs = (PyObject **)args - 1; PyObject *tmp = newargs[0]; newargs[0] = pto_args[0]; - PyObject *ret = _PyObject_Vectorcall(pto->fn, newargs, nargs + 1, kwnames); + PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn, + newargs, nargs + 1, kwnames); newargs[0] = tmp; return ret; } @@ -195,7 +201,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*)); memcpy(stack + pto_nargs, args, nargs_total * sizeof(PyObject*)); - ret = _PyObject_Vectorcall(pto->fn, stack, pto_nargs + nargs, kwnames); + ret = _PyObject_VectorcallTstate(tstate, pto->fn, + stack, pto_nargs + nargs, kwnames); if (stack != small_stack) { PyMem_Free(stack); } diff --git a/Objects/call.c b/Objects/call.c index a1d0b332cefcc..a8ae41a7842ae 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -104,7 +104,7 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, vectorcallfunc func = _PyVectorcall_Function(callable); if (func == NULL) { /* Use tp_call instead */ - return _PyObject_MakeTpCall(callable, args, nargs, kwargs); + return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); } PyObject *res; @@ -129,10 +129,10 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, PyObject * -_PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) +_PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, + PyObject *const *args, Py_ssize_t nargs, + PyObject *keywords) { - PyThreadState *tstate = _PyThreadState_GET(); - /* Slow path: build a temporary tuple for positional arguments and a * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; @@ -774,6 +774,7 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, assert(args != NULL); assert(PyVectorcall_NARGS(nargsf) >= 1); + PyThreadState *tstate = _PyThreadState_GET(); PyObject *callable = NULL; /* Use args[0] as "self" argument */ int unbound = _PyObject_GetMethod(args[0], name, &callable); @@ -792,7 +793,8 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, args++; nargsf--; } - PyObject *result = _PyObject_Vectorcall(callable, args, nargsf, kwnames); + PyObject *result = _PyObject_VectorcallTstate(tstate, callable, + args, nargsf, kwnames); Py_DECREF(callable); return result; } diff --git a/Objects/classobject.c b/Objects/classobject.c index 4a9add1229e37..d3fc726415406 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" @@ -37,25 +38,28 @@ method_vectorcall(PyObject *method, PyObject *const *args, size_t nargsf, PyObject *kwnames) { assert(Py_TYPE(method) == &PyMethod_Type); - PyObject *self, *func, *result; - self = PyMethod_GET_SELF(method); - func = PyMethod_GET_FUNCTION(method); + + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *self = PyMethod_GET_SELF(method); + PyObject *func = PyMethod_GET_FUNCTION(method); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *result; if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ PyObject **newargs = (PyObject**)args - 1; nargs += 1; PyObject *tmp = newargs[0]; newargs[0] = self; - result = _PyObject_Vectorcall(func, newargs, nargs, kwnames); + result = _PyObject_VectorcallTstate(tstate, func, newargs, + nargs, kwnames); newargs[0] = tmp; } else { Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); Py_ssize_t totalargs = nargs + nkwargs; if (totalargs == 0) { - return _PyObject_Vectorcall(func, &self, 1, NULL); + return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL); } PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; @@ -66,7 +70,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, else { newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); if (newargs == NULL) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } } @@ -77,7 +81,8 @@ method_vectorcall(PyObject *method, PyObject *const *args, * undefined behaviour. */ assert(args != NULL); memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); - result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); + result = _PyObject_VectorcallTstate(tstate, func, + newargs, nargs+1, kwnames); if (newargs != newargs_stack) { PyMem_Free(newargs); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 0e1cb7b7aeb36..50a3c15785a90 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1445,7 +1445,7 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound) static inline PyObject* -vectorcall_unbound(int unbound, PyObject *func, +vectorcall_unbound(PyThreadState *tstate, int unbound, PyObject *func, PyObject *const *args, Py_ssize_t nargs) { size_t nargsf = nargs; @@ -1455,7 +1455,7 @@ vectorcall_unbound(int unbound, PyObject *func, args++; nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; } - return _PyObject_Vectorcall(func, args, nargsf, NULL); + return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } static PyObject* @@ -1479,13 +1479,15 @@ vectorcall_method(_Py_Identifier *name, PyObject *const *args, Py_ssize_t nargs) { assert(nargs >= 1); + + PyThreadState *tstate = _PyThreadState_GET(); int unbound; PyObject *self = args[0]; PyObject *func = lookup_method(self, name, &unbound); if (func == NULL) { return NULL; } - PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); + PyObject *retval = vectorcall_unbound(tstate, unbound, func, args, nargs); Py_DECREF(func); return retval; } @@ -1493,10 +1495,11 @@ vectorcall_method(_Py_Identifier *name, /* Clone of vectorcall_method() that returns NotImplemented * when the lookup fails. */ static PyObject * -vectorcall_maybe(_Py_Identifier *name, +vectorcall_maybe(PyThreadState *tstate, _Py_Identifier *name, PyObject *const *args, Py_ssize_t nargs) { assert(nargs >= 1); + int unbound; PyObject *self = args[0]; PyObject *func = lookup_maybe_method(self, name, &unbound); @@ -1505,7 +1508,7 @@ vectorcall_maybe(_Py_Identifier *name, Py_RETURN_NOTIMPLEMENTED; return NULL; } - PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); + PyObject *retval = vectorcall_unbound(tstate, unbound, func, args, nargs); Py_DECREF(func); return retval; } @@ -6177,6 +6180,7 @@ static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ PyObject* stack[2]; \ + PyThreadState *tstate = _PyThreadState_GET(); \ _Py_static_string(op_id, OPSTR); \ _Py_static_string(rop_id, ROPSTR); \ int do_other = Py_TYPE(self) != Py_TYPE(other) && \ @@ -6193,7 +6197,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (ok) { \ stack[0] = other; \ stack[1] = self; \ - r = vectorcall_maybe(&rop_id, stack, 2); \ + r = vectorcall_maybe(tstate, &rop_id, stack, 2); \ if (r != Py_NotImplemented) \ return r; \ Py_DECREF(r); \ @@ -6202,7 +6206,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ } \ stack[0] = self; \ stack[1] = other; \ - r = vectorcall_maybe(&op_id, stack, 2); \ + r = vectorcall_maybe(tstate, &op_id, stack, 2); \ if (r != Py_NotImplemented || \ Py_TYPE(other) == Py_TYPE(self)) \ return r; \ @@ -6211,7 +6215,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (do_other) { \ stack[0] = other; \ stack[1] = self; \ - return vectorcall_maybe(&rop_id, stack, 2); \ + return vectorcall_maybe(tstate, &rop_id, stack, 2); \ } \ Py_RETURN_NOTIMPLEMENTED; \ } @@ -6293,6 +6297,7 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) static int slot_sq_contains(PyObject *self, PyObject *value) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *func, *res; int result = -1, unbound; _Py_IDENTIFIER(__contains__); @@ -6307,7 +6312,7 @@ slot_sq_contains(PyObject *self, PyObject *value) } if (func != NULL) { PyObject *args[2] = {self, value}; - res = vectorcall_unbound(unbound, func, args, 2); + res = vectorcall_unbound(tstate, unbound, func, args, 2); Py_DECREF(func); if (res != NULL) { result = PyObject_IsTrue(res); @@ -6682,6 +6687,7 @@ static _Py_Identifier name_op[] = { static PyObject * slot_tp_richcompare(PyObject *self, PyObject *other, int op) { + PyThreadState *tstate = _PyThreadState_GET(); int unbound; PyObject *func, *res; @@ -6692,7 +6698,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op) } PyObject *stack[2] = {self, other}; - res = vectorcall_unbound(unbound, func, stack, 2); + res = vectorcall_unbound(tstate, unbound, func, stack, 2); Py_DECREF(func); return res; } diff --git a/Python/context.c b/Python/context.c index f48c376b4ffaa..26f22994eecb7 100644 --- a/Python/context.c +++ b/Python/context.c @@ -3,6 +3,7 @@ #include "pycore_context.h" #include "pycore_hamt.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "structmember.h" @@ -101,21 +102,18 @@ PyContext_CopyCurrent(void) } -int -PyContext_Enter(PyObject *octx) +static int +_PyContext_Enter(PyThreadState *ts, PyObject *octx) { ENSURE_Context(octx, -1) PyContext *ctx = (PyContext *)octx; if (ctx->ctx_entered) { - PyErr_Format(PyExc_RuntimeError, - "cannot enter context: %R is already entered", ctx); + _PyErr_Format(ts, PyExc_RuntimeError, + "cannot enter context: %R is already entered", ctx); return -1; } - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - ctx->ctx_prev = (PyContext *)ts->context; /* borrow */ ctx->ctx_entered = 1; @@ -128,7 +126,16 @@ PyContext_Enter(PyObject *octx) int -PyContext_Exit(PyObject *octx) +PyContext_Enter(PyObject *octx) +{ + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + return _PyContext_Enter(ts, octx); +} + + +static int +_PyContext_Exit(PyThreadState *ts, PyObject *octx) { ENSURE_Context(octx, -1) PyContext *ctx = (PyContext *)octx; @@ -139,9 +146,6 @@ PyContext_Exit(PyObject *octx) return -1; } - PyThreadState *ts = _PyThreadState_GET(); - assert(ts != NULL); - if (ts->context != (PyObject *)ctx) { /* Can only happen if someone misuses the C API */ PyErr_SetString(PyExc_RuntimeError, @@ -159,6 +163,14 @@ PyContext_Exit(PyObject *octx) return 0; } +int +PyContext_Exit(PyObject *octx) +{ + PyThreadState *ts = _PyThreadState_GET(); + assert(ts != NULL); + return _PyContext_Exit(ts, octx); +} + PyObject * PyContextVar_New(const char *name, PyObject *def) @@ -621,20 +633,22 @@ static PyObject * context_run(PyContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + PyThreadState *ts = _PyThreadState_GET(); + if (nargs < 1) { - PyErr_SetString(PyExc_TypeError, - "run() missing 1 required positional argument"); + _PyErr_SetString(ts, PyExc_TypeError, + "run() missing 1 required positional argument"); return NULL; } - if (PyContext_Enter((PyObject *)self)) { + if (_PyContext_Enter(ts, (PyObject *)self)) { return NULL; } - PyObject *call_result = _PyObject_Vectorcall( - args[0], args + 1, nargs - 1, kwnames); + PyObject *call_result = _PyObject_VectorcallTstate( + ts, args[0], args + 1, nargs - 1, kwnames); - if (PyContext_Exit((PyObject *)self)) { + if (_PyContext_Exit(ts, (PyObject *)self)) { return NULL; } From webhook-mailer at python.org Fri Nov 8 15:26:45 2019 From: webhook-mailer at python.org (Carol Willing) Date: Fri, 08 Nov 2019 20:26:45 -0000 Subject: [Python-checkins] Clarify amount of dots between package and subpackage (GH-17092) Message-ID: https://github.com/python/cpython/commit/fc6b1bf869be9fd89c19faf8d12fa473ce5222c8 commit: fc6b1bf869be9fd89c19faf8d12fa473ce5222c8 branch: master author: Shu <23287722+susan-shu-c at users.noreply.github.com> committer: Carol Willing date: 2019-11-08T12:26:35-08:00 summary: Clarify amount of dots between package and subpackage (GH-17092) files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 0228bfb7e984c..5cce8ceaa3cb6 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -83,7 +83,7 @@ module. Specifically, any module that contains a ``__path__`` attribute is considered a package. All modules have a name. Subpackage names are separated from their parent -package name by dots, akin to Python's standard attribute access syntax. Thus +package name by a dot, akin to Python's standard attribute access syntax. Thus you might have a module called :mod:`sys` and a package called :mod:`email`, which in turn has a subpackage called :mod:`email.mime` and a module within that subpackage called :mod:`email.mime.text`. From webhook-mailer at python.org Sat Nov 9 06:12:33 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 09 Nov 2019 11:12:33 -0000 Subject: [Python-checkins] bpo-22367: Add tests for fcntl.lockf(). (GH-17010) Message-ID: https://github.com/python/cpython/commit/85e415108226cc5f3fdddd70196fc4c2a1d0f7f4 commit: 85e415108226cc5f3fdddd70196fc4c2a1d0f7f4 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-09T03:12:28-08:00 summary: bpo-22367: Add tests for fcntl.lockf(). (GH-17010) (cherry picked from commit befa032d8869e0fab4732d910f3887642879d644) Co-authored-by: Dong-hee Na files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 5d4abe388f782..88d989d5e358d 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -5,6 +5,7 @@ import struct import sys import unittest +from multiprocessing import Process from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, cpython_only) @@ -12,7 +13,6 @@ fcntl = import_module('fcntl') -# TODO - Write tests for flock() and lockf(). def get_lockdata(): try: @@ -138,6 +138,33 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + def test_lockf_exclusive(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_EX | fcntl.LOCK_NB + def try_lockf_on_other_process(): + self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + + def test_lockf_share(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_SH | fcntl.LOCK_NB + def try_lockf_on_other_process(): + fcntl.lockf(self.f, cmd) + fcntl.lockf(self.f, fcntl.LOCK_UN) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + @cpython_only def test_flock_overflow(self): import _testcapi From webhook-mailer at python.org Sat Nov 9 06:12:40 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 09 Nov 2019 11:12:40 -0000 Subject: [Python-checkins] bpo-22367: Add tests for fcntl.lockf(). (GH-17010) Message-ID: https://github.com/python/cpython/commit/917dbe350a762ed6d75b7d074f3fb87975ba717b commit: 917dbe350a762ed6d75b7d074f3fb87975ba717b branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-09T03:12:35-08:00 summary: bpo-22367: Add tests for fcntl.lockf(). (GH-17010) (cherry picked from commit befa032d8869e0fab4732d910f3887642879d644) Co-authored-by: Dong-hee Na files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index acd5c7cc58647..30eeb6dc4d02a 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -5,6 +5,7 @@ import struct import sys import unittest +from multiprocessing import Process from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, cpython_only) @@ -12,7 +13,6 @@ fcntl = import_module('fcntl') -# TODO - Write tests for flock() and lockf(). def get_lockdata(): try: @@ -138,6 +138,33 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + def test_lockf_exclusive(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_EX | fcntl.LOCK_NB + def try_lockf_on_other_process(): + self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + + def test_lockf_share(self): + self.f = open(TESTFN, 'wb+') + cmd = fcntl.LOCK_SH | fcntl.LOCK_NB + def try_lockf_on_other_process(): + fcntl.lockf(self.f, cmd) + fcntl.lockf(self.f, fcntl.LOCK_UN) + + fcntl.lockf(self.f, cmd) + p = Process(target=try_lockf_on_other_process) + p.start() + p.join() + fcntl.lockf(self.f, fcntl.LOCK_UN) + self.assertEqual(p.exitcode, 0) + @cpython_only def test_flock_overflow(self): import _testcapi From webhook-mailer at python.org Sat Nov 9 06:13:40 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 09 Nov 2019 11:13:40 -0000 Subject: [Python-checkins] bpo-38635: Simplify decoding the ZIP64 extra field and make it tolerant to extra data. (GH-16988) Message-ID: https://github.com/python/cpython/commit/e27449da92b13730a5e11182f329d5da98a5e05b commit: e27449da92b13730a5e11182f329d5da98a5e05b branch: master author: Serhiy Storchaka committer: GitHub date: 2019-11-09T13:13:36+02:00 summary: bpo-38635: Simplify decoding the ZIP64 extra field and make it tolerant to extra data. (GH-16988) files: M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 6504e0eee8b5a..b0afb9da942b1 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -465,44 +465,23 @@ def _decodeExtra(self): if ln+4 > len(extra): raise BadZipFile("Corrupt extra field %04x (size=%d)" % (tp, ln)) if tp == 0x0001: - if ln >= 24: - counts = unpack(' https://github.com/python/cpython/commit/af46450bb97ab9bd38748e75aa849c29fdd70028 commit: af46450bb97ab9bd38748e75aa849c29fdd70028 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-09T20:28:31-08:00 summary: Minor readability improvement for argument handling in itertools.repeat() (GH-17101) files: M Modules/itertoolsmodule.c diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 3d39fa2e4737b..0cb472966d1f9 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -4256,17 +4256,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { repeatobject *ro; PyObject *element; - Py_ssize_t cnt = -1, n_kwds = 0; + Py_ssize_t cnt = -1, n_args; static char *kwargs[] = {"object", "times", NULL}; + n_args = PyTuple_GET_SIZE(args); + if (kwds != NULL) + n_args += PyDict_GET_SIZE(kwds); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, &element, &cnt)) return NULL; - - if (kwds != NULL) - n_kwds = PyDict_GET_SIZE(kwds); /* Does user supply times argument? */ - if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0) + if (n_args == 2 && cnt < 0) cnt = 0; ro = (repeatobject *)type->tp_alloc(type, 0); From webhook-mailer at python.org Sun Nov 10 23:12:24 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 11 Nov 2019 04:12:24 -0000 Subject: [Python-checkins] bpo-38761: Register WeakSet as a MutableSet (GH-17104) Message-ID: https://github.com/python/cpython/commit/84ac4376587e35d16b4d0977c4f330d9d04b690a commit: 84ac4376587e35d16b4d0977c4f330d9d04b690a branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-10T20:12:04-08:00 summary: bpo-38761: Register WeakSet as a MutableSet (GH-17104) files: A Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst M Lib/test/test_weakset.py M Lib/weakref.py diff --git a/Lib/test/test_weakset.py b/Lib/test/test_weakset.py index 569facdd30c11..49a9b5c3c658a 100644 --- a/Lib/test/test_weakset.py +++ b/Lib/test/test_weakset.py @@ -2,6 +2,7 @@ from weakref import WeakSet import string from collections import UserString as ustr +from collections.abc import Set, MutableSet import gc import contextlib @@ -437,6 +438,10 @@ def test_len_race(self): def test_repr(self): assert repr(self.s) == repr(self.s.data) + def test_abc(self): + self.assertIsInstance(self.s, Set) + self.assertIsInstance(self.s, MutableSet) + if __name__ == "__main__": unittest.main() diff --git a/Lib/weakref.py b/Lib/weakref.py index d17b3ed38eacb..e3c2ce2d9b8b8 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -33,6 +33,9 @@ "WeakSet", "WeakMethod", "finalize"] +_collections_abc.Set.register(WeakSet) +_collections_abc.MutableSet.register(WeakSet) + class WeakMethod(ref): """ A custom `weakref.ref` subclass which simulates a weak reference to diff --git a/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst b/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst new file mode 100644 index 0000000000000..4dde5ebc3208c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst @@ -0,0 +1 @@ +WeakSet is now registered as a collections.abc.MutableSet. From webhook-mailer at python.org Mon Nov 11 15:47:58 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 11 Nov 2019 20:47:58 -0000 Subject: [Python-checkins] bpo-38438: Simplify argparse "star nargs" usage. (GH-17106) Message-ID: https://github.com/python/cpython/commit/a0ed99bca8475cbc82e9202aa354faba2a4620f4 commit: a0ed99bca8475cbc82e9202aa354faba2a4620f4 branch: master author: Brandt Bucher committer: Raymond Hettinger date: 2019-11-11T12:47:48-08:00 summary: bpo-38438: Simplify argparse "star nargs" usage. (GH-17106) files: A Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst M Doc/library/argparse.rst M Doc/library/pdb.rst M Lib/argparse.py M Lib/pydoc_data/topics.py M Lib/test/test_argparse.py diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 818acf484cdf3..9a1cf3a53c442 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -449,7 +449,7 @@ default values to each of the argument help messages:: >>> parser.add_argument('--foo', type=int, default=42, help='FOO!') >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!') >>> parser.print_help() - usage: PROG [-h] [--foo FOO] [bar [bar ...]] + usage: PROG [-h] [--foo FOO] [bar ...] positional arguments: bar BAR! (default: [1, 2, 3]) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index f26b6a8b553b3..0b9a687b14e3a 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -296,20 +296,20 @@ by the local file. Temporary breakpoint, which is removed automatically when it is first hit. The arguments are the same as for :pdbcmd:`break`. -.. pdbcommand:: cl(ear) [filename:lineno | bpnumber [bpnumber ...]] +.. pdbcommand:: cl(ear) [filename:lineno | bpnumber ...] With a *filename:lineno* argument, clear all the breakpoints at this line. With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation). -.. pdbcommand:: disable [bpnumber [bpnumber ...]] +.. pdbcommand:: disable [bpnumber ...] Disable the breakpoints given as a space separated list of breakpoint numbers. Disabling a breakpoint means it cannot cause the program to stop execution, but unlike clearing a breakpoint, it remains in the list of breakpoints and can be (re-)enabled. -.. pdbcommand:: enable [bpnumber [bpnumber ...]] +.. pdbcommand:: enable [bpnumber ...] Enable the breakpoints specified. diff --git a/Lib/argparse.py b/Lib/argparse.py index 13af7ac239217..94e1b8ad0ed18 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -591,7 +591,11 @@ def _format_args(self, action, default_metavar): elif action.nargs == OPTIONAL: result = '[%s]' % get_metavar(1) elif action.nargs == ZERO_OR_MORE: - result = '[%s [%s ...]]' % get_metavar(2) + metavar = get_metavar(1) + if len(metavar) == 2: + result = '[%s [%s ...]]' % metavar + else: + result = '[%s ...]' % metavar elif action.nargs == ONE_OR_MORE: result = '%s [%s ...]' % get_metavar(2) elif action.nargs == REMAINDER: diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 1fb19f241ac31..d3559e445ab01 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -3903,7 +3903,7 @@ 'is\n' ' first hit. The arguments are the same as for "break".\n' '\n' - 'cl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n' + 'cl(ear) [filename:lineno | bpnumber ...]\n' '\n' ' With a *filename:lineno* argument, clear all the breakpoints ' 'at\n' @@ -3913,7 +3913,7 @@ 'first\n' ' ask confirmation).\n' '\n' - 'disable [bpnumber [bpnumber ...]]\n' + 'disable [bpnumber ...]\n' '\n' ' Disable the breakpoints given as a space separated list of\n' ' breakpoint numbers. Disabling a breakpoint means it cannot ' @@ -3922,7 +3922,7 @@ 'breakpoint, it\n' ' remains in the list of breakpoints and can be (re-)enabled.\n' '\n' - 'enable [bpnumber [bpnumber ...]]\n' + 'enable [bpnumber ...]\n' '\n' ' Enable the breakpoints specified.\n' '\n' diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index a97c921852c7b..60bf19918b79e 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2163,7 +2163,7 @@ def test_subparser1_help(self): def test_subparser2_help(self): self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\ - usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]] + usage: PROG bar 2 [-h] [-y {1,2,3}] [z ...] 2 description @@ -2697,10 +2697,10 @@ def get_parser(self, required): ] usage_when_not_required = '''\ - usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]] + usage: PROG [-h] [--foo | --spam SPAM | badger ...] ''' usage_when_required = '''\ - usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...]) + usage: PROG [-h] (--foo | --spam SPAM | badger ...) ''' help = '''\ @@ -3494,11 +3494,11 @@ class TestHelpUsage(HelpTestCase): ]) ] usage = '''\ - usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [--foo | --no-foo] + usage: PROG [-h] [-w W [W ...]] [-x [X ...]] [--foo | --no-foo] [--bar | --no-bar] [-f | --foobar | --no-foobar | --barfoo | --no-barfoo] [-y [Y]] [-z Z Z Z] - a b b [c] [d [d ...]] e [e ...] + a b b [c] [d ...] e [e ...] ''' help = usage + '''\ @@ -3510,7 +3510,7 @@ class TestHelpUsage(HelpTestCase): optional arguments: -h, --help show this help message and exit -w W [W ...] w - -x [X [X ...]] x + -x [X ...] x --foo, --no-foo Whether to foo --bar, --no-bar Whether to bar (default: True) -f, --foobar, --no-foobar, --barfoo, --no-barfoo @@ -5113,7 +5113,7 @@ def test_nargs_zeroormore_metavar_length0(self): self.do_test_exception(nargs="*", metavar=tuple()) def test_nargs_zeroormore_metavar_length1(self): - self.do_test_exception(nargs="*", metavar=("1",)) + self.do_test_no_exception(nargs="*", metavar=("1",)) def test_nargs_zeroormore_metavar_length2(self): self.do_test_no_exception(nargs="*", metavar=("1", "2")) diff --git a/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst b/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst new file mode 100644 index 0000000000000..69ea2de02f73a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst @@ -0,0 +1 @@ +Simplify the :mod:`argparse` usage message for ``nargs="*"``. \ No newline at end of file From webhook-mailer at python.org Mon Nov 11 19:50:00 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 00:50:00 -0000 Subject: [Python-checkins] bpo-38771: Explict test for None in code example (GH-17108) Message-ID: https://github.com/python/cpython/commit/98480cef9dba04794bd61c7e7cca643d384c8c35 commit: 98480cef9dba04794bd61c7e7cca643d384c8c35 branch: master author: Jonathan Scholbach committer: Raymond Hettinger date: 2019-11-11T16:49:41-08:00 summary: bpo-38771: Explict test for None in code example (GH-17108) files: M Doc/library/collections.rst diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 90a3f4bea9a45..a5e8d04099b22 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -162,7 +162,7 @@ environment variables which in turn take precedence over default values:: parser.add_argument('-u', '--user') parser.add_argument('-c', '--color') namespace = parser.parse_args() - command_line_args = {k:v for k, v in vars(namespace).items() if v} + command_line_args = {k: v for k, v in vars(namespace).items() if v is not None} combined = ChainMap(command_line_args, os.environ, defaults) print(combined['color']) From webhook-mailer at python.org Mon Nov 11 19:58:56 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 00:58:56 -0000 Subject: [Python-checkins] bpo-38771: Explict test for None in code example (GH-17108) (GH-17110) Message-ID: https://github.com/python/cpython/commit/cb1c06e3bfbce7f4e8dcb0db84bcee54c8d4fa21 commit: cb1c06e3bfbce7f4e8dcb0db84bcee54c8d4fa21 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-11T16:58:49-08:00 summary: bpo-38771: Explict test for None in code example (GH-17108) (GH-17110) (cherry picked from commit 98480cef9dba04794bd61c7e7cca643d384c8c35) Co-authored-by: Jonathan Scholbach files: M Doc/library/collections.rst diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index e9dbd094e0a96..6488b1260d206 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -162,7 +162,7 @@ environment variables which in turn take precedence over default values:: parser.add_argument('-u', '--user') parser.add_argument('-c', '--color') namespace = parser.parse_args() - command_line_args = {k:v for k, v in vars(namespace).items() if v} + command_line_args = {k: v for k, v in vars(namespace).items() if v is not None} combined = ChainMap(command_line_args, os.environ, defaults) print(combined['color']) From webhook-mailer at python.org Mon Nov 11 19:59:18 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 00:59:18 -0000 Subject: [Python-checkins] bpo-38771: Explict test for None in code example (GH-17108) (GH-17109) Message-ID: https://github.com/python/cpython/commit/d8e08456025d9349abbf76035c821d3f7b2d722a commit: d8e08456025d9349abbf76035c821d3f7b2d722a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-11T16:59:14-08:00 summary: bpo-38771: Explict test for None in code example (GH-17108) (GH-17109) (cherry picked from commit 98480cef9dba04794bd61c7e7cca643d384c8c35) Co-authored-by: Jonathan Scholbach files: M Doc/library/collections.rst diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 90a3f4bea9a45..a5e8d04099b22 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -162,7 +162,7 @@ environment variables which in turn take precedence over default values:: parser.add_argument('-u', '--user') parser.add_argument('-c', '--color') namespace = parser.parse_args() - command_line_args = {k:v for k, v in vars(namespace).items() if v} + command_line_args = {k: v for k, v in vars(namespace).items() if v is not None} combined = ChainMap(command_line_args, os.environ, defaults) print(combined['color']) From webhook-mailer at python.org Tue Nov 12 02:30:27 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 07:30:27 -0000 Subject: [Python-checkins] bpo-38565: add new cache_parameters method for lru_cache (GH-16916) Message-ID: https://github.com/python/cpython/commit/051ff526b5dc2c40c4a53d87089740358822edfa commit: 051ff526b5dc2c40c4a53d87089740358822edfa branch: master author: Manjusaka committer: Raymond Hettinger date: 2019-11-11T23:30:18-08:00 summary: bpo-38565: add new cache_parameters method for lru_cache (GH-16916) files: A Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst M Doc/library/functools.rst M Lib/functools.py M Lib/test/test_functools.py diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index d3debac8432b1..cedc3ad5ec0a6 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -108,6 +108,11 @@ The :mod:`functools` module defines the following functions: cached separately. For example, ``f(3)`` and ``f(3.0)`` will be treated as distinct calls with distinct results. + The wrapped function is instrumented with a :func:`cache_parameters` + function that returns a new :class:`dict` showing the values for *maxsize* + and *typed*. This is for information purposes only. Mutating the values + has no effect. + To help measure the effectiveness of the cache and tune the *maxsize* parameter, the wrapped function is instrumented with a :func:`cache_info` function that returns a :term:`named tuple` showing *hits*, *misses*, @@ -178,6 +183,9 @@ The :mod:`functools` module defines the following functions: .. versionchanged:: 3.8 Added the *user_function* option. + .. versionadded:: 3.9 + Added the function :func:`cache_parameters` + .. decorator:: total_ordering Given a class defining one or more rich comparison ordering methods, this diff --git a/Lib/functools.py b/Lib/functools.py index 3192bd02d93e5..2c01b2e59524b 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -499,6 +499,7 @@ def lru_cache(maxsize=128, typed=False): # The user_function was passed in directly via the maxsize argument user_function, maxsize = maxsize, 128 wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) + wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed} return update_wrapper(wrapper, user_function) elif maxsize is not None: raise TypeError( @@ -506,6 +507,7 @@ def lru_cache(maxsize=128, typed=False): def decorating_function(user_function): wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) + wrapper.cache_parameters = lambda : {'maxsize': maxsize, 'typed': typed} return update_wrapper(wrapper, user_function) return decorating_function diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index c300270d49e5e..a97ca398e77a3 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -1655,6 +1655,17 @@ def orig(x, y): f_copy = copy.deepcopy(f) self.assertIs(f_copy, f) + def test_lru_cache_parameters(self): + @self.module.lru_cache(maxsize=2) + def f(): + return 1 + self.assertEqual(f.cache_parameters(), {'maxsize': 2, "typed": False}) + + @self.module.lru_cache(maxsize=1000, typed=True) + def f(): + return 1 + self.assertEqual(f.cache_parameters(), {'maxsize': 1000, "typed": True}) + @py_functools.lru_cache() def py_cached_func(x, y): diff --git a/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst b/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst new file mode 100644 index 0000000000000..34d7afcf36df6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst @@ -0,0 +1 @@ +Add new cache_parameters() method for functools.lru_cache() to better support pickling. \ No newline at end of file From webhook-mailer at python.org Tue Nov 12 02:35:10 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 07:35:10 -0000 Subject: [Python-checkins] bpo-38385: Fix iterator/iterable terminology in statistics docs (GH-17111) Message-ID: https://github.com/python/cpython/commit/733b9a308e3c49855888e2e12397ae56d831e780 commit: 733b9a308e3c49855888e2e12397ae56d831e780 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-11T23:35:06-08:00 summary: bpo-38385: Fix iterator/iterable terminology in statistics docs (GH-17111) files: M Doc/library/statistics.rst M Lib/statistics.py diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 00c0b539edce9..a790ed81a5607 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -77,7 +77,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: mean(data) - Return the sample arithmetic mean of *data* which can be a sequence or iterator. + Return the sample arithmetic mean of *data* which can be a sequence or iterable. The arithmetic mean is the sum of the data divided by the number of data points. It is commonly called "the average", although it is only one of many @@ -122,7 +122,7 @@ However, for reading convenience, most of the examples show sorted sequences. Convert *data* to floats and compute the arithmetic mean. This runs faster than the :func:`mean` function and it always returns a - :class:`float`. The *data* may be a sequence or iterator. If the input + :class:`float`. The *data* may be a sequence or iterable. If the input dataset is empty, raises a :exc:`StatisticsError`. .. doctest:: @@ -143,7 +143,7 @@ However, for reading convenience, most of the examples show sorted sequences. Raises a :exc:`StatisticsError` if the input dataset is empty, if it contains a zero, or if it contains a negative value. - The *data* may be a sequence or iterator. + The *data* may be a sequence or iterable. No special efforts are made to achieve exact results. (However, this may change in the future.) @@ -158,7 +158,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: harmonic_mean(data) - Return the harmonic mean of *data*, a sequence or iterator of + Return the harmonic mean of *data*, a sequence or iterable of real-valued numbers. The harmonic mean, sometimes called the subcontrary mean, is the @@ -202,7 +202,7 @@ However, for reading convenience, most of the examples show sorted sequences. Return the median (middle value) of numeric data, using the common "mean of middle two" method. If *data* is empty, :exc:`StatisticsError` is raised. - *data* can be a sequence or iterator. + *data* can be a sequence or iterable. The median is a robust measure of central location and is less affected by the presence of outliers. When the number of data points is odd, the @@ -231,7 +231,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: median_low(data) Return the low median of numeric data. If *data* is empty, - :exc:`StatisticsError` is raised. *data* can be a sequence or iterator. + :exc:`StatisticsError` is raised. *data* can be a sequence or iterable. The low median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the smaller of @@ -251,7 +251,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: median_high(data) Return the high median of data. If *data* is empty, :exc:`StatisticsError` - is raised. *data* can be a sequence or iterator. + is raised. *data* can be a sequence or iterable. The high median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the larger of @@ -272,7 +272,7 @@ However, for reading convenience, most of the examples show sorted sequences. Return the median of grouped continuous data, calculated as the 50th percentile, using interpolation. If *data* is empty, :exc:`StatisticsError` - is raised. *data* can be a sequence or iterator. + is raised. *data* can be a sequence or iterable. .. doctest:: @@ -381,7 +381,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: pvariance(data, mu=None) - Return the population variance of *data*, a non-empty sequence or iterator + Return the population variance of *data*, a non-empty sequence or iterable of real-valued numbers. Variance, or second moment about the mean, is a measure of the variability (spread or dispersion) of data. A large variance indicates that the data is spread out; a small variance indicates diff --git a/Lib/statistics.py b/Lib/statistics.py index 461ffae3f4914..1e95c0b6639f1 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -744,7 +744,7 @@ def variance(data, xbar=None): def pvariance(data, mu=None): """Return the population variance of ``data``. - data should be a sequence or iterator of Real-valued numbers, with at least one + data should be a sequence or iterable of Real-valued numbers, with at least one value. The optional argument mu, if given, should be the mean of the data. If it is missing or None, the mean is automatically calculated. From webhook-mailer at python.org Tue Nov 12 03:04:21 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 12 Nov 2019 08:04:21 -0000 Subject: [Python-checkins] bpo-38385: Fix iterator/iterable terminology in statistics docs (GH-17111) (GH-17113) Message-ID: https://github.com/python/cpython/commit/3562439eb293c5fe90b1f1fe507d57d2f4fcd044 commit: 3562439eb293c5fe90b1f1fe507d57d2f4fcd044 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-12T00:04:12-08:00 summary: bpo-38385: Fix iterator/iterable terminology in statistics docs (GH-17111) (GH-17113) (cherry picked from commit 733b9a308e3c49855888e2e12397ae56d831e780) Co-authored-by: Raymond Hettinger files: M Doc/library/statistics.rst M Lib/statistics.py diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 00c0b539edce9..a790ed81a5607 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -77,7 +77,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: mean(data) - Return the sample arithmetic mean of *data* which can be a sequence or iterator. + Return the sample arithmetic mean of *data* which can be a sequence or iterable. The arithmetic mean is the sum of the data divided by the number of data points. It is commonly called "the average", although it is only one of many @@ -122,7 +122,7 @@ However, for reading convenience, most of the examples show sorted sequences. Convert *data* to floats and compute the arithmetic mean. This runs faster than the :func:`mean` function and it always returns a - :class:`float`. The *data* may be a sequence or iterator. If the input + :class:`float`. The *data* may be a sequence or iterable. If the input dataset is empty, raises a :exc:`StatisticsError`. .. doctest:: @@ -143,7 +143,7 @@ However, for reading convenience, most of the examples show sorted sequences. Raises a :exc:`StatisticsError` if the input dataset is empty, if it contains a zero, or if it contains a negative value. - The *data* may be a sequence or iterator. + The *data* may be a sequence or iterable. No special efforts are made to achieve exact results. (However, this may change in the future.) @@ -158,7 +158,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: harmonic_mean(data) - Return the harmonic mean of *data*, a sequence or iterator of + Return the harmonic mean of *data*, a sequence or iterable of real-valued numbers. The harmonic mean, sometimes called the subcontrary mean, is the @@ -202,7 +202,7 @@ However, for reading convenience, most of the examples show sorted sequences. Return the median (middle value) of numeric data, using the common "mean of middle two" method. If *data* is empty, :exc:`StatisticsError` is raised. - *data* can be a sequence or iterator. + *data* can be a sequence or iterable. The median is a robust measure of central location and is less affected by the presence of outliers. When the number of data points is odd, the @@ -231,7 +231,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: median_low(data) Return the low median of numeric data. If *data* is empty, - :exc:`StatisticsError` is raised. *data* can be a sequence or iterator. + :exc:`StatisticsError` is raised. *data* can be a sequence or iterable. The low median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the smaller of @@ -251,7 +251,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: median_high(data) Return the high median of data. If *data* is empty, :exc:`StatisticsError` - is raised. *data* can be a sequence or iterator. + is raised. *data* can be a sequence or iterable. The high median is always a member of the data set. When the number of data points is odd, the middle value is returned. When it is even, the larger of @@ -272,7 +272,7 @@ However, for reading convenience, most of the examples show sorted sequences. Return the median of grouped continuous data, calculated as the 50th percentile, using interpolation. If *data* is empty, :exc:`StatisticsError` - is raised. *data* can be a sequence or iterator. + is raised. *data* can be a sequence or iterable. .. doctest:: @@ -381,7 +381,7 @@ However, for reading convenience, most of the examples show sorted sequences. .. function:: pvariance(data, mu=None) - Return the population variance of *data*, a non-empty sequence or iterator + Return the population variance of *data*, a non-empty sequence or iterable of real-valued numbers. Variance, or second moment about the mean, is a measure of the variability (spread or dispersion) of data. A large variance indicates that the data is spread out; a small variance indicates diff --git a/Lib/statistics.py b/Lib/statistics.py index 461ffae3f4914..1e95c0b6639f1 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -744,7 +744,7 @@ def variance(data, xbar=None): def pvariance(data, mu=None): """Return the population variance of ``data``. - data should be a sequence or iterator of Real-valued numbers, with at least one + data should be a sequence or iterable of Real-valued numbers, with at least one value. The optional argument mu, if given, should be the mean of the data. If it is missing or None, the mean is automatically calculated. From webhook-mailer at python.org Tue Nov 12 05:02:58 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 12 Nov 2019 10:02:58 -0000 Subject: [Python-checkins] [3.8] bpo-37309: idlelib/NEWS.txt - add missing period. (#17115) Message-ID: https://github.com/python/cpython/commit/8341a4d918ca96f8a5523444e056ffa82fa039d5 commit: 8341a4d918ca96f8a5523444e056ffa82fa039d5 branch: 3.8 author: Terry Jan Reedy committer: GitHub date: 2019-11-12T05:02:48-05:00 summary: [3.8] bpo-37309: idlelib/NEWS.txt - add missing period. (#17115) files: M Lib/idlelib/NEWS.txt diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 04d9bb84b7920..47f66fa40b675 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,7 @@ Released on 2019-12-16? ====================================== -bpo-38598: Do not try to compile IDLE shell or output windows +bpo-38598: Do not try to compile IDLE shell or output windows. What's New in IDLE 3.8.0 (since 3.7.0) From webhook-mailer at python.org Tue Nov 12 05:21:10 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 10:21:10 -0000 Subject: [Python-checkins] [3.8] bpo-37309: idlelib/NEWS.txt - add missing period. (GH-17115) Message-ID: https://github.com/python/cpython/commit/832341a07158955c2df899c18779b72fb379b0d0 commit: 832341a07158955c2df899c18779b72fb379b0d0 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T02:21:06-08:00 summary: [3.8] bpo-37309: idlelib/NEWS.txt - add missing period. (GH-17115) (cherry picked from commit 8341a4d918ca96f8a5523444e056ffa82fa039d5) Co-authored-by: Terry Jan Reedy files: M Lib/idlelib/NEWS.txt diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 6ced11f23729a..fb22fb5e2bce0 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,7 @@ Released on 2019-12-16? ====================================== -bpo-38598: Do not try to compile IDLE shell or output windows +bpo-38598: Do not try to compile IDLE shell or output windows. What's New in IDLE 3.7.5 From webhook-mailer at python.org Tue Nov 12 05:54:14 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Tue, 12 Nov 2019 10:54:14 -0000 Subject: [Python-checkins] bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) Message-ID: https://github.com/python/cpython/commit/c8b53dc3d8f721ed8519aa5a35530a42fbfb9424 commit: c8b53dc3d8f721ed8519aa5a35530a42fbfb9424 branch: master author: Zackery Spytz committer: Terry Jan Reedy date: 2019-11-12T05:54:10-05:00 summary: bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) files: A Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index ce96baf32859c..938c9c7d06b05 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2020-10-05? ====================================== +bop-26353: Stop adding newline when saving an IDLE shell window. + bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 743a05b3c3134..99f4048796712 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,14 +1,13 @@ -"Test , coverage 16%." +"Test , coverage 17%." from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk - from idlelib.editor import EditorWindow -class IOBindigTest(unittest.TestCase): +class IOBindingTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -16,9 +15,11 @@ def setUpClass(cls): cls.root = Tk() cls.root.withdraw() cls.editwin = EditorWindow(root=cls.root) + cls.io = iomenu.IOBinding(cls.editwin) @classmethod def tearDownClass(cls): + cls.io.close() cls.editwin._close() del cls.editwin cls.root.update_idletasks() @@ -28,9 +29,20 @@ def tearDownClass(cls): del cls.root def test_init(self): - io = iomenu.IOBinding(self.editwin) - self.assertIs(io.editwin, self.editwin) - io.close + self.assertIs(self.io.editwin, self.editwin) + + def test_fixnewlines_end(self): + eq = self.assertEqual + io = self.io + fix = io.fixnewlines + text = io.editwin.text + self.editwin.interp = None + eq(fix(), '') + del self.editwin.interp + text.insert(1.0, 'a') + eq(fix(), 'a'+io.eol_convention) + eq(text.get('1.0', 'end-1c'), 'a\n') + eq(fix(), 'a'+io.eol_convention) if __name__ == '__main__': diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index b5533be79f996..4b2833b8ca56f 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -371,10 +371,7 @@ def save_a_copy(self, event): return "break" def writefile(self, filename): - self.fixlastline() - text = self.text.get("1.0", "end-1c") - if self.eol_convention != "\n": - text = text.replace("\n", self.eol_convention) + text = self.fixnewlines() chars = self.encode(text) try: with open(filename, "wb") as f: @@ -387,6 +384,16 @@ def writefile(self, filename): parent=self.text) return False + def fixnewlines(self): + "Return text with final \n if needed and os eols." + if (self.text.get("end-2c") != '\n' + and not hasattr(self.editwin, "interp")): # Not shell. + self.text.insert("end-1c", "\n") + text = self.text.get("1.0", "end-1c") + if self.eol_convention != "\n": + text = text.replace("\n", self.eol_convention) + return text + def encode(self, chars): if isinstance(chars, bytes): # This is either plain ASCII, or Tk was returning mixed-encoding @@ -426,11 +433,6 @@ def encode(self, chars): # declared encoding return BOM_UTF8 + chars.encode("utf-8") - def fixlastline(self): - c = self.text.get("end-2c") - if c != '\n': - self.text.insert("end-1c", "\n") - def print_window(self, event): confirm = tkMessageBox.askokcancel( title="Print", diff --git a/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst new file mode 100644 index 0000000000000..fd0a2a3682100 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst @@ -0,0 +1,2 @@ +Stop adding newline when saving an IDLE shell window. + From webhook-mailer at python.org Tue Nov 12 06:13:41 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 11:13:41 -0000 Subject: [Python-checkins] bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) Message-ID: https://github.com/python/cpython/commit/177b12682cad7edf9cdea91382acc4232c0167e6 commit: 177b12682cad7edf9cdea91382acc4232c0167e6 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T03:13:32-08:00 summary: bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) (cherry picked from commit c8b53dc3d8f721ed8519aa5a35530a42fbfb9424) Co-authored-by: Zackery Spytz files: A Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index fb22fb5e2bce0..81bf746a5cba3 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bop-26353: Stop adding newline when saving an IDLE shell window. + bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 743a05b3c3134..99f4048796712 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,14 +1,13 @@ -"Test , coverage 16%." +"Test , coverage 17%." from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk - from idlelib.editor import EditorWindow -class IOBindigTest(unittest.TestCase): +class IOBindingTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -16,9 +15,11 @@ def setUpClass(cls): cls.root = Tk() cls.root.withdraw() cls.editwin = EditorWindow(root=cls.root) + cls.io = iomenu.IOBinding(cls.editwin) @classmethod def tearDownClass(cls): + cls.io.close() cls.editwin._close() del cls.editwin cls.root.update_idletasks() @@ -28,9 +29,20 @@ def tearDownClass(cls): del cls.root def test_init(self): - io = iomenu.IOBinding(self.editwin) - self.assertIs(io.editwin, self.editwin) - io.close + self.assertIs(self.io.editwin, self.editwin) + + def test_fixnewlines_end(self): + eq = self.assertEqual + io = self.io + fix = io.fixnewlines + text = io.editwin.text + self.editwin.interp = None + eq(fix(), '') + del self.editwin.interp + text.insert(1.0, 'a') + eq(fix(), 'a'+io.eol_convention) + eq(text.get('1.0', 'end-1c'), 'a\n') + eq(fix(), 'a'+io.eol_convention) if __name__ == '__main__': diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index b5533be79f996..4b2833b8ca56f 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -371,10 +371,7 @@ def save_a_copy(self, event): return "break" def writefile(self, filename): - self.fixlastline() - text = self.text.get("1.0", "end-1c") - if self.eol_convention != "\n": - text = text.replace("\n", self.eol_convention) + text = self.fixnewlines() chars = self.encode(text) try: with open(filename, "wb") as f: @@ -387,6 +384,16 @@ def writefile(self, filename): parent=self.text) return False + def fixnewlines(self): + "Return text with final \n if needed and os eols." + if (self.text.get("end-2c") != '\n' + and not hasattr(self.editwin, "interp")): # Not shell. + self.text.insert("end-1c", "\n") + text = self.text.get("1.0", "end-1c") + if self.eol_convention != "\n": + text = text.replace("\n", self.eol_convention) + return text + def encode(self, chars): if isinstance(chars, bytes): # This is either plain ASCII, or Tk was returning mixed-encoding @@ -426,11 +433,6 @@ def encode(self, chars): # declared encoding return BOM_UTF8 + chars.encode("utf-8") - def fixlastline(self): - c = self.text.get("end-2c") - if c != '\n': - self.text.insert("end-1c", "\n") - def print_window(self, event): confirm = tkMessageBox.askokcancel( title="Print", diff --git a/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst new file mode 100644 index 0000000000000..fd0a2a3682100 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst @@ -0,0 +1,2 @@ +Stop adding newline when saving an IDLE shell window. + From webhook-mailer at python.org Tue Nov 12 06:13:41 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 11:13:41 -0000 Subject: [Python-checkins] bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) Message-ID: https://github.com/python/cpython/commit/8ce1a9ce038d1a5fda03ae76964002857a2a52f9 commit: 8ce1a9ce038d1a5fda03ae76964002857a2a52f9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T03:13:18-08:00 summary: bpo-26353: IDLE adds an unneeded newline when saving a shell window (GH-17103) (cherry picked from commit c8b53dc3d8f721ed8519aa5a35530a42fbfb9424) Co-authored-by: Zackery Spytz files: A Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/idle_test/test_iomenu.py M Lib/idlelib/iomenu.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 47f66fa40b675..5e6686a89e44d 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-12-16? ====================================== +bop-26353: Stop adding newline when saving an IDLE shell window. + bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 743a05b3c3134..99f4048796712 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,14 +1,13 @@ -"Test , coverage 16%." +"Test , coverage 17%." from idlelib import iomenu import unittest from test.support import requires from tkinter import Tk - from idlelib.editor import EditorWindow -class IOBindigTest(unittest.TestCase): +class IOBindingTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -16,9 +15,11 @@ def setUpClass(cls): cls.root = Tk() cls.root.withdraw() cls.editwin = EditorWindow(root=cls.root) + cls.io = iomenu.IOBinding(cls.editwin) @classmethod def tearDownClass(cls): + cls.io.close() cls.editwin._close() del cls.editwin cls.root.update_idletasks() @@ -28,9 +29,20 @@ def tearDownClass(cls): del cls.root def test_init(self): - io = iomenu.IOBinding(self.editwin) - self.assertIs(io.editwin, self.editwin) - io.close + self.assertIs(self.io.editwin, self.editwin) + + def test_fixnewlines_end(self): + eq = self.assertEqual + io = self.io + fix = io.fixnewlines + text = io.editwin.text + self.editwin.interp = None + eq(fix(), '') + del self.editwin.interp + text.insert(1.0, 'a') + eq(fix(), 'a'+io.eol_convention) + eq(text.get('1.0', 'end-1c'), 'a\n') + eq(fix(), 'a'+io.eol_convention) if __name__ == '__main__': diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index b5533be79f996..4b2833b8ca56f 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -371,10 +371,7 @@ def save_a_copy(self, event): return "break" def writefile(self, filename): - self.fixlastline() - text = self.text.get("1.0", "end-1c") - if self.eol_convention != "\n": - text = text.replace("\n", self.eol_convention) + text = self.fixnewlines() chars = self.encode(text) try: with open(filename, "wb") as f: @@ -387,6 +384,16 @@ def writefile(self, filename): parent=self.text) return False + def fixnewlines(self): + "Return text with final \n if needed and os eols." + if (self.text.get("end-2c") != '\n' + and not hasattr(self.editwin, "interp")): # Not shell. + self.text.insert("end-1c", "\n") + text = self.text.get("1.0", "end-1c") + if self.eol_convention != "\n": + text = text.replace("\n", self.eol_convention) + return text + def encode(self, chars): if isinstance(chars, bytes): # This is either plain ASCII, or Tk was returning mixed-encoding @@ -426,11 +433,6 @@ def encode(self, chars): # declared encoding return BOM_UTF8 + chars.encode("utf-8") - def fixlastline(self): - c = self.text.get("end-2c") - if c != '\n': - self.text.insert("end-1c", "\n") - def print_window(self, event): confirm = tkMessageBox.askokcancel( title="Print", diff --git a/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst new file mode 100644 index 0000000000000..fd0a2a3682100 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst @@ -0,0 +1,2 @@ +Stop adding newline when saving an IDLE shell window. + From webhook-mailer at python.org Tue Nov 12 07:29:43 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Tue, 12 Nov 2019 12:29:43 -0000 Subject: [Python-checkins] bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) Message-ID: https://github.com/python/cpython/commit/106271568c58cfebae58f0c52b640dbe716ba2ce commit: 106271568c58cfebae58f0c52b640dbe716ba2ce branch: master author: Vinay Sajip committer: GitHub date: 2019-11-12T12:29:34Z summary: bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) files: M Lib/ctypes/test/test_structures.py M Modules/_ctypes/_ctypes.c M Modules/_ctypes/_ctypes_test.c diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index ab23206df8a76..283ccbf7237bb 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -656,6 +656,87 @@ class Test5(Structure): self.assertEqual(test5.nested.an_int, 0) self.assertEqual(test5.another_int, 0) + #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390') + def test_bitfield_by_value(self): + # See bpo-16576 + + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c + + class Test6(Structure): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test6 = Test6() + # As these are signed int fields, all are logically -1 due to sign + # extension. + test6.A = 1 + test6.B = 3 + test6.C = 7 + test6.D = 3 + dll = CDLL(_ctypes_test.__file__) + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value1 + func.restype = c_long + func.argtypes = (Test6,) + result = func(test6) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a struct/union with a bitfield by value, which is ' + 'unsupported.') + # passing by reference should be OK + func = dll._testfunc_bitfield_by_reference1 + func.restype = c_long + func.argtypes = (POINTER(Test6),) + result = func(byref(test6)) + self.assertEqual(result, -4) + self.assertEqual(test6.A, 0) + self.assertEqual(test6.B, 0) + self.assertEqual(test6.C, 0) + self.assertEqual(test6.D, 0) + + class Test7(Structure): + _fields_ = [ + ('A', c_uint, 1), + ('B', c_uint, 2), + ('C', c_uint, 3), + ('D', c_uint, 2), + ] + test7 = Test7() + test7.A = 1 + test7.B = 3 + test7.C = 7 + test7.D = 3 + func = dll._testfunc_bitfield_by_reference2 + func.restype = c_long + func.argtypes = (POINTER(Test7),) + result = func(byref(test7)) + self.assertEqual(result, 14) + self.assertEqual(test7.A, 0) + self.assertEqual(test7.B, 0) + self.assertEqual(test7.C, 0) + self.assertEqual(test7.D, 0) + + # for a union with bitfields, the union check happens first + class Test8(Union): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test8 = Test8() + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value2 + func.restype = c_long + func.argtypes = (Test8,) + result = func(test8) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 5e22b73155c5f..b4a3fc433d279 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2400,11 +2400,18 @@ converters_from_argtypes(PyObject *ob) } return NULL; } - /* if (stgdict->flags & TYPEFLAG_HASBITFIELD) { - printf("found stgdict with bitfield\n"); + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a struct/" + "union with a bitfield by value, which is " + "unsupported.", + i + 1); + } + return NULL; } - */ } if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 49ed82004f604..8fbc22ff29753 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -194,6 +194,56 @@ _testfunc_union_by_reference3(Test5 *in) { return result; } +typedef struct { + signed int A: 1, B:2, C:3, D:2; +} Test6; + +EXPORT(long) +_testfunc_bitfield_by_value1(Test6 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_bitfield_by_reference1(Test6 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test6)); + return result; +} + +typedef struct { + unsigned int A: 1, B:2, C:3, D:2; +} Test7; + +EXPORT(long) +_testfunc_bitfield_by_reference2(Test7 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test7)); + return result; +} + +typedef union { + signed int A: 1, B:2, C:3, D:2; +} Test8; + +EXPORT(long) +_testfunc_bitfield_by_value2(Test8 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", From webhook-mailer at python.org Tue Nov 12 07:38:55 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 12:38:55 -0000 Subject: [Python-checkins] bpo-38421: Update email.utils documentation (GH-16678) Message-ID: https://github.com/python/cpython/commit/a12255d8def0c82560545e66c1be981a447751c3 commit: a12255d8def0c82560545e66c1be981a447751c3 branch: master author: David K committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-12T04:38:46-08:00 summary: bpo-38421: Update email.utils documentation (GH-16678) Updates documentation around email.utils.parsedate_tz(). Currently, the documentation specifies that when a string without a is timezone passed to parsedate_tz(), the last tuple is returned as ```None```. This is no longer true since Python 3.3 https://bugs.python.org/issue38421 files: M Doc/library/email.utils.rst diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 63fae2ab84e21..4d0e920eb0ad2 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -117,8 +117,8 @@ of the new API. a 10-tuple; the first 9 elements make up a tuple that can be passed directly to :func:`time.mktime`, and the tenth is the offset of the date's timezone from UTC (which is the official term for Greenwich Mean Time) [#]_. If the input string - has no timezone, the last element of the tuple returned is ``None``. Note that - indexes 6, 7, and 8 of the result tuple are not usable. + has no timezone, the last element of the tuple returned is ``0``, which represents + UTC. Note that indexes 6, 7, and 8 of the result tuple are not usable. .. function:: parsedate_to_datetime(date) From webhook-mailer at python.org Tue Nov 12 08:08:05 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 13:08:05 -0000 Subject: [Python-checkins] bpo-36974: expand call protocol documentation (GH-13844) Message-ID: https://github.com/python/cpython/commit/9a13a388f202268dd7b771638adbec132449b98b commit: 9a13a388f202268dd7b771638adbec132449b98b branch: master author: Jeroen Demeyer committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-12T05:08:00-08:00 summary: bpo-36974: expand call protocol documentation (GH-13844) CC @encukou I'm also adding Petr Viktorin as contributor for vectorcall in the "what's new" section. https://bugs.python.org/issue36974 Automerge-Triggered-By: @encukou Automerge-Triggered-By: @encukou files: A Doc/c-api/call.rst M Doc/c-api/abstract.rst M Doc/c-api/exceptions.rst M Doc/c-api/object.rst M Doc/c-api/structures.rst M Doc/c-api/type.rst M Doc/c-api/typeobj.rst M Doc/whatsnew/3.8.rst diff --git a/Doc/c-api/abstract.rst b/Doc/c-api/abstract.rst index 0edd1d5f6240a..1823f9d70c79f 100644 --- a/Doc/c-api/abstract.rst +++ b/Doc/c-api/abstract.rst @@ -18,6 +18,7 @@ but whose items have not been set to some non-\ ``NULL`` value yet. .. toctree:: object.rst + call.rst number.rst sequence.rst mapping.rst diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst new file mode 100644 index 0000000000000..0833531b1d5ee --- /dev/null +++ b/Doc/c-api/call.rst @@ -0,0 +1,411 @@ +.. highlight:: c + +.. _call: + +Call Protocol +============= + +CPython supports two different calling protocols: +*tp_call* and vectorcall. + +The *tp_call* Protocol +---------------------- + +Instances of classes that set :c:member:`~PyTypeObject.tp_call` are callable. +The signature of the slot is:: + + PyObject *tp_call(PyObject *callable, PyObject *args, PyObject *kwargs); + +A call is made using a tuple for the positional arguments +and a dict for the keyword arguments, similarly to +``callable(*args, **kwargs)`` in Python code. +*args* must be non-NULL (use an empty tuple if there are no arguments) +but *kwargs* may be *NULL* if there are no keyword arguments. + +This convention is not only used by *tp_call*: +:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_init` +also pass arguments this way. + +To call an object, use :c:func:`PyObject_Call` or other +:ref:`call API `. + + +.. _vectorcall: + +The Vectorcall Protocol +----------------------- + +.. versionadded:: 3.8 + +The vectorcall protocol was introduced in :pep:`590` as an additional protocol +for making calls more efficient. + +.. warning:: + + The vectorcall API is provisional and expected to become public in + Python 3.9, with a different names and, possibly, changed semantics. + If you use the it, plan for updating your code for Python 3.9. + +As rule of thumb, CPython will prefer the vectorcall for internal calls +if the callable supports it. However, this is not a hard rule. +Additionally, some third-party extensions use *tp_call* directly +(rather than using :c:func:`PyObject_Call`). +Therefore, a class supporting vectorcall must also implement +:c:member:`~PyTypeObject.tp_call`. +Moreover, the callable must behave the same +regardless of which protocol is used. +The recommended way to achieve this is by setting +:c:member:`~PyTypeObject.tp_call` to :c:func:`PyVectorcall_Call`. +This bears repeating: + +.. warning:: + + A class supporting vectorcall **must** also implement + :c:member:`~PyTypeObject.tp_call` with the same semantics. + +A class should not implement vectorcall if that would be slower +than *tp_call*. For example, if the callee needs to convert +the arguments to an args tuple and kwargs dict anyway, then there is no point +in implementing vectorcall. + +Classes can implement the vectorcall protocol by enabling the +:const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag and setting +:c:member:`~PyTypeObject.tp_vectorcall_offset` to the offset inside the +object structure where a *vectorcallfunc* appears. +This is a pointer to a function with the following signature: + +.. c:type:: PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) + +- *callable* is the object being called. +- *args* is a C array consisting of the positional arguments followed by the + values of the keyword arguments. + This can be *NULL* if there are no arguments. +- *nargsf* is the number of positional arguments plus possibly the + :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` flag. + To get the actual number of positional arguments from *nargsf*, + use :c:func:`PyVectorcall_NARGS`. +- *kwnames* is a tuple containing the names of the keyword arguments; + in other words, the keys of the kwargs dict. + These names must be strings (instances of ``str`` or a subclass) + and they must be unique. + If there are no keyword arguments, then *kwnames* can instead be *NULL*. + +.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET + + If this flag is set in a vectorcall *nargsf* argument, the callee is allowed + to temporarily change ``args[-1]``. In other words, *args* points to + argument 1 (not 0) in the allocated vector. + The callee must restore the value of ``args[-1]`` before returning. + + For :c:func:`_PyObject_VectorcallMethod`, this flag means instead that + ``args[0]`` may be changed. + + Whenever they can do so cheaply (without additional allocation), callers + are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + Doing so will allow callables such as bound methods to make their onward + calls (which include a prepended *self* argument) very efficiently. + +To call an object that implements vectorcall, use a :ref:`call API ` +function as with any other callable. +:c:func:`_PyObject_Vectorcall` will usually be most efficient. + + +Recursion Control +................. + +When using *tp_call*, callees do not need to worry about +:ref:`recursion `: CPython uses +:c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` +for calls made using *tp_call*. + +For efficiency, this is not the case for calls done using vectorcall: +the callee should use *Py_EnterRecursiveCall* and *Py_LeaveRecursiveCall* +if needed. + + +Vectorcall Support API +...................... + +.. c:function:: Py_ssize_t PyVectorcall_NARGS(size_t nargsf) + + Given a vectorcall *nargsf* argument, return the actual number of + arguments. + Currently equivalent to:: + + (Py_ssize_t)(nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET) + + However, the function ``PyVectorcall_NARGS`` should be used to allow + for future extensions. + + .. versionadded:: 3.8 + +.. c:function:: vectorcallfunc _PyVectorcall_Function(PyObject *op) + + If *op* does not support the vectorcall protocol (either because the type + does not or because the specific instance does not), return *NULL*. + Otherwise, return the vectorcall function pointer stored in *op*. + This function never raises an exception. + + This is mostly useful to check whether or not *op* supports vectorcall, + which can be done by checking ``_PyVectorcall_Function(op) != NULL``. + + .. versionadded:: 3.8 + +.. c:function:: PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict) + + Call *callable*'s :c:type:`vectorcallfunc` with positional and keyword + arguments given in a tuple and dict, respectively. + + This is a specialized function, intended to be put in the + :c:member:`~PyTypeObject.tp_call` slot or be used in an implementation of ``tp_call``. + It does not check the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag + and it does not fall back to ``tp_call``. + + .. versionadded:: 3.8 + + +.. _capi-call: + +Object Calling API +------------------ + +Various functions are available for calling a Python object. +Each converts its arguments to a convention supported by the called object ? +either *tp_call* or vectorcall. +In order to do as litle conversion as possible, pick one that best fits +the format of data you have available. + +The following table summarizes the available functions; +please see individual documentation for details. + ++------------------------------------------+------------------+--------------------+---------------+ +| Function | callable | args | kwargs | ++==========================================+==================+====================+===============+ +| :c:func:`PyObject_Call` | ``PyObject *`` | tuple | dict/``NULL`` | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallNoArgs` | ``PyObject *`` | --- | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_CallOneArg` | ``PyObject *`` | 1 object | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallObject` | ``PyObject *`` | tuple/``NULL`` | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallFunction` | ``PyObject *`` | format | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallMethod` | obj + ``char*`` | format | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallFunctionObjArgs` | ``PyObject *`` | variadic | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`PyObject_CallMethodObjArgs` | obj + name | variadic | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_CallMethodNoArgs` | obj + name | --- | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_CallMethodOneArg` | obj + name | 1 object | --- | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_Vectorcall` | ``PyObject *`` | vectorcall | vectorcall | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_FastCallDict` | ``PyObject *`` | vectorcall | dict/``NULL`` | ++------------------------------------------+------------------+--------------------+---------------+ +| :c:func:`_PyObject_VectorcallMethod` | arg + name | vectorcall | vectorcall | ++------------------------------------------+------------------+--------------------+---------------+ + + +.. c:function:: PyObject* PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) + + Call a callable Python object *callable*, with arguments given by the + tuple *args*, and named arguments given by the dictionary *kwargs*. + + *args* must not be *NULL*; use an empty tuple if no arguments are needed. + If no named arguments are needed, *kwargs* can be *NULL*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + This is the equivalent of the Python expression: + ``callable(*args, **kwargs)``. + + +.. c:function:: PyObject* PyObject_CallNoArgs(PyObject *callable) + + Call a callable Python object *callable* without any arguments. It is the + most efficient way to call a callable Python object without any argument. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + +.. c:function:: PyObject* _PyObject_CallOneArg(PyObject *callable, PyObject *arg) + + Call a callable Python object *callable* with exactly 1 positional argument + *arg* and no keyword arguments. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + +.. c:function:: PyObject* PyObject_CallObject(PyObject *callable, PyObject *args) + + Call a callable Python object *callable*, with arguments given by the + tuple *args*. If no arguments are needed, then *args* can be *NULL*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + This is the equivalent of the Python expression: ``callable(*args)``. + + +.. c:function:: PyObject* PyObject_CallFunction(PyObject *callable, const char *format, ...) + + Call a callable Python object *callable*, with a variable number of C arguments. + The C arguments are described using a :c:func:`Py_BuildValue` style format + string. The format can be *NULL*, indicating that no arguments are provided. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + This is the equivalent of the Python expression: ``callable(*args)``. + + Note that if you only pass :c:type:`PyObject \*` args, + :c:func:`PyObject_CallFunctionObjArgs` is a faster alternative. + + .. versionchanged:: 3.4 + The type of *format* was changed from ``char *``. + + +.. c:function:: PyObject* PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) + + Call the method named *name* of object *obj* with a variable number of C + arguments. The C arguments are described by a :c:func:`Py_BuildValue` format + string that should produce a tuple. + + The format can be *NULL*, indicating that no arguments are provided. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + This is the equivalent of the Python expression: + ``obj.name(arg1, arg2, ...)``. + + Note that if you only pass :c:type:`PyObject \*` args, + :c:func:`PyObject_CallMethodObjArgs` is a faster alternative. + + .. versionchanged:: 3.4 + The types of *name* and *format* were changed from ``char *``. + + +.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) + + Call a callable Python object *callable*, with a variable number of + :c:type:`PyObject \*` arguments. The arguments are provided as a variable number + of parameters followed by *NULL*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + This is the equivalent of the Python expression: + ``callable(arg1, arg2, ...)``. + + +.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ..., NULL) + + Call a method of the Python object *obj*, where the name of the method is given as a + Python string object in *name*. It is called with a variable number of + :c:type:`PyObject \*` arguments. The arguments are provided as a variable number + of parameters followed by *NULL*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + +.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name) + + Call a method of the Python object *obj* without arguments, + where the name of the method is given as a Python string object in *name*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + +.. c:function:: PyObject* _PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg) + + Call a method of the Python object *obj* with a single positional argument + *arg*, where the name of the method is given as a Python string object in + *name*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + +.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) + + Call a callable Python object *callable*. + The arguments are the same as for :c:type:`vectorcallfunc`. + If *callable* supports vectorcall_, this directly calls + the vectorcall function stored in *callable*. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. note:: + + This function is provisional and expected to become public in Python 3.9, + with a different name and, possibly, changed semantics. + If you use the function, plan for updating your code for Python 3.9. + + .. versionadded:: 3.8 + +.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict) + + Call *callable* with positional arguments passed exactly as in the vectorcall_ protocol, + but with keyword arguments passed as a dictionary *kwdict*. + The *args* array contains only the positional arguments. + + Regardless of which protocol is used internally, + a conversion of arguments needs to be done. + Therefore, this function should only be used if the caller + already has a dictionary ready to use for the keyword arguments, + but not a tuple for the positional arguments. + + .. note:: + + This function is provisional and expected to become public in Python 3.9, + with a different name and, possibly, changed semantics. + If you use the function, plan for updating your code for Python 3.9. + + .. versionadded:: 3.8 + +.. c:function:: PyObject* _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) + + Call a method using the vectorcall calling convention. The name of the method + is given as a Python string *name*. The object whose method is called is + *args[0]*, and the *args* array starting at *args[1]* represents the arguments + of the call. There must be at least one positional argument. + *nargsf* is the number of positional arguments including *args[0]*, + plus :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may + temporarily be changed. Keyword arguments can be passed just like in + :c:func:`_PyObject_Vectorcall`. + + If the object has the :const:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, + this will call the unbound method object with the full + *args* vector as arguments. + + Return the result of the call on success, or raise an exception and return + *NULL* on failure. + + .. versionadded:: 3.9 + + +Call Support API +---------------- + +.. c:function:: int PyCallable_Check(PyObject *o) + + Determine if the object *o* is callable. Return ``1`` if the object is callable + and ``0`` otherwise. This function always succeeds. diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index cd6df00aeb5cd..2edcbf788d2ad 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -697,6 +697,8 @@ The following functions are used to create and modify Unicode exceptions from C. ``0`` on success, ``-1`` on failure. +.. _recursion: + Recursion Control ================= @@ -704,6 +706,8 @@ These two functions provide a way to perform safe recursive calls at the C level, both in the core and in extension modules. They are needed if the recursive code does not necessarily invoke Python code (which tracks its recursion depth automatically). +They are also not needed for *tp_call* implementations +because the :ref:`call protocol ` takes care of recursion handling. .. c:function:: int Py_EnterRecursiveCall(const char *where) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 7d7a3be02fabc..ca9db1aee2f87 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -248,246 +248,6 @@ Object Protocol of base classes). -.. c:function:: int PyCallable_Check(PyObject *o) - - Determine if the object *o* is callable. Return ``1`` if the object is callable - and ``0`` otherwise. This function always succeeds. - - -.. c:function:: PyObject* PyObject_CallNoArgs(PyObject *callable) - - Call a callable Python object *callable* without any arguments. It is the - most efficient way to call a callable Python object without any argument. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - .. versionadded:: 3.9 - - -.. c:function:: PyObject* _PyObject_CallOneArg(PyObject *callable, PyObject *arg) - - Call a callable Python object *callable* with exactly 1 positional argument - *arg* and no keyword arguments. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - .. versionadded:: 3.9 - - -.. c:function:: PyObject* PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) - - Call a callable Python object *callable*, with arguments given by the - tuple *args*, and named arguments given by the dictionary *kwargs*. - - *args* must not be ``NULL``, use an empty tuple if no arguments are needed. - If no named arguments are needed, *kwargs* can be ``NULL``. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This is the equivalent of the Python expression: - ``callable(*args, **kwargs)``. - - -.. c:function:: PyObject* PyObject_CallObject(PyObject *callable, PyObject *args) - - Call a callable Python object *callable*, with arguments given by the - tuple *args*. If no arguments are needed, then *args* can be ``NULL``. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This is the equivalent of the Python expression: ``callable(*args)``. - - -.. c:function:: PyObject* PyObject_CallFunction(PyObject *callable, const char *format, ...) - - Call a callable Python object *callable*, with a variable number of C arguments. - The C arguments are described using a :c:func:`Py_BuildValue` style format - string. The format can be ``NULL``, indicating that no arguments are provided. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This is the equivalent of the Python expression: ``callable(*args)``. - - Note that if you only pass :c:type:`PyObject \*` args, - :c:func:`PyObject_CallFunctionObjArgs` is a faster alternative. - - .. versionchanged:: 3.4 - The type of *format* was changed from ``char *``. - - -.. c:function:: PyObject* PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) - - Call the method named *name* of object *obj* with a variable number of C - arguments. The C arguments are described by a :c:func:`Py_BuildValue` format - string that should produce a tuple. - - The format can be ``NULL``, indicating that no arguments are provided. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This is the equivalent of the Python expression: - ``obj.name(arg1, arg2, ...)``. - - Note that if you only pass :c:type:`PyObject \*` args, - :c:func:`PyObject_CallMethodObjArgs` is a faster alternative. - - .. versionchanged:: 3.4 - The types of *name* and *format* were changed from ``char *``. - - -.. c:function:: PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ..., NULL) - - Call a callable Python object *callable*, with a variable number of - :c:type:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by ``NULL``. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This is the equivalent of the Python expression: - ``callable(arg1, arg2, ...)``. - - -.. c:function:: PyObject* PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ..., NULL) - - Calls a method of the Python object *obj*, where the name of the method is given as a - Python string object in *name*. It is called with a variable number of - :c:type:`PyObject\*` arguments. The arguments are provided as a variable number - of parameters followed by ``NULL``. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - -.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name) - - Call a method of the Python object *obj* without arguments, - where the name of the method is given as a Python string object in *name*. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - .. versionadded:: 3.9 - - -.. c:function:: PyObject* _PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg) - - Call a method of the Python object *obj* with a single positional argument - *arg*, where the name of the method is given as a Python string object in - *name*. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - .. versionadded:: 3.9 - - -.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) - - Call a callable Python object *callable*, using - :c:data:`vectorcall ` if possible. - - *args* is a C array with the positional arguments. - - *nargsf* is the number of positional arguments plus optionally the flag - :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` (see below). - To get actual number of arguments, use - :c:func:`PyVectorcall_NARGS(nargsf) `. - - *kwnames* can be either ``NULL`` (no keyword arguments) or a tuple of keyword - names, which must be strings. In the latter case, the values of the keyword - arguments are stored in *args* after the positional arguments. - The number of keyword arguments does not influence *nargsf*. - - *kwnames* must contain only objects of type ``str`` (not a subclass), - and all keys must be unique. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - This uses the vectorcall protocol if the callable supports it; - otherwise, the arguments are converted to use - :c:member:`~PyTypeObject.tp_call`. - - .. note:: - - This function is provisional and expected to become public in Python 3.9, - with a different name and, possibly, changed semantics. - If you use the function, plan for updating your code for Python 3.9. - - .. versionadded:: 3.8 - -.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET - - If set in a vectorcall *nargsf* argument, the callee is allowed to - temporarily change ``args[-1]``. In other words, *args* points to - argument 1 (not 0) in the allocated vector. - The callee must restore the value of ``args[-1]`` before returning. - - For :c:func:`_PyObject_VectorcallMethod`, this flag means instead that - ``args[0]`` may be changed. - - Whenever they can do so cheaply (without additional allocation), callers - are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. - Doing so will allow callables such as bound methods to make their onward - calls (which include a prepended *self* argument) cheaply. - - .. versionadded:: 3.8 - -.. c:function:: Py_ssize_t PyVectorcall_NARGS(size_t nargsf) - - Given a vectorcall *nargsf* argument, return the actual number of - arguments. - Currently equivalent to ``nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET``. - - .. versionadded:: 3.8 - -.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict) - - Same as :c:func:`_PyObject_Vectorcall` except that the keyword arguments - are passed as a dictionary in *kwdict*. This may be ``NULL`` if there - are no keyword arguments. - - For callables supporting :c:data:`vectorcall `, - the arguments are internally converted to the vectorcall convention. - Therefore, this function adds some overhead compared to - :c:func:`_PyObject_Vectorcall`. - It should only be used if the caller already has a dictionary ready to use. - - .. note:: - - This function is provisional and expected to become public in Python 3.9, - with a different name and, possibly, changed semantics. - If you use the function, plan for updating your code for Python 3.9. - - .. versionadded:: 3.8 - -.. c:function:: PyObject* _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) - - Call a method using the vectorcall calling convention. The name of the method - is given as Python string *name*. The object whose method is called is - *args[0]* and the *args* array starting at *args[1]* represents the arguments - of the call. There must be at least one positional argument. - *nargsf* is the number of positional arguments including *args[0]*, - plus :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may - temporarily be changed. Keyword arguments can be passed just like in - :c:func:`_PyObject_Vectorcall`. - - If the object has the :const:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, - this will actually call the unbound method object with the full - *args* vector as arguments. - - Return the result of the call on success, or raise an exception and return - ``NULL`` on failure. - - .. versionadded:: 3.9 - .. c:function:: Py_hash_t PyObject_Hash(PyObject *o) .. index:: builtin: hash diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 10352778f33b7..1bd769f275b35 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -208,7 +208,8 @@ also keyword arguments. So there are a total of 6 calling conventions: Extension of :const:`METH_FASTCALL` supporting also keyword arguments, with methods of type :c:type:`_PyCFunctionFastWithKeywords`. - Keyword arguments are passed the same way as in the vectorcall protocol: + Keyword arguments are passed the same way as in the + :ref:`vectorcall protocol `: there is an additional fourth :c:type:`PyObject\*` parameter which is a tuple representing the names of the keyword arguments (which are guaranteed to be strings) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index b1b2df9f19042..41956b7dca503 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -193,6 +193,7 @@ The following functions and structs are used to create (see :ref:`PyMemberDef `) * :c:member:`~PyTypeObject.tp_dictoffset` (see :ref:`PyMemberDef `) + * :c:member:`~PyTypeObject.tp_vectorcall_offset` * :c:member:`~PyBufferProcs.bf_getbuffer` * :c:member:`~PyBufferProcs.bf_releasebuffer` diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index bff5abfea48ee..b4ffd6b41c628 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -49,7 +49,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | | | ? | + | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | | | | __getattr__ | | | | | @@ -145,6 +145,8 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ If :const:`COUNT_ALLOCS` is defined then the following (internal-only) fields exist as well: @@ -180,7 +182,7 @@ fields exist as well: .. code-block:: none - X - type slot is inherited via PyType_Ready if defined with a NULL value + X - type slot is inherited via *PyType_Ready* if defined with a *NULL* value % - the slots of the sub-struct are inherited individually G - inherited, but only in combination with other slots; see the slot's description ? - it's complicated; see the slot's description @@ -687,42 +689,29 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_vectorcall_offset An optional offset to a per-instance function that implements calling - the object using the *vectorcall* protocol, a more efficient alternative + the object using the :ref:`vectorcall protocol `, + a more efficient alternative of the simpler :c:member:`~PyTypeObject.tp_call`. This field is only used if the flag :const:`_Py_TPFLAGS_HAVE_VECTORCALL` is set. If so, this must be a positive integer containing the offset in the instance of a :c:type:`vectorcallfunc` pointer. - The signature is the same as for :c:func:`_PyObject_Vectorcall`:: - - PyObject *vectorcallfunc(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) - The *vectorcallfunc* pointer may be zero, in which case the instance behaves + The *vectorcallfunc* pointer may be ``NULL``, in which case the instance behaves as if :const:`_Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance falls back to :c:member:`~PyTypeObject.tp_call`. Any class that sets ``_Py_TPFLAGS_HAVE_VECTORCALL`` must also set :c:member:`~PyTypeObject.tp_call` and make sure its behaviour is consistent with the *vectorcallfunc* function. - This can be done by setting *tp_call* to ``PyVectorcall_Call``: - - .. c:function:: PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict) + This can be done by setting *tp_call* to :c:func:`PyVectorcall_Call`. - Call *callable*'s *vectorcallfunc* with positional and keyword - arguments given in a tuple and dict, respectively. - - This function is intended to be used in the ``tp_call`` slot. - It does not fall back to ``tp_call`` and it currently does not check the - ``_Py_TPFLAGS_HAVE_VECTORCALL`` flag. - To call an object, use one of the :c:func:`PyObject_Call ` - functions instead. - - .. note:: + .. warning:: It is not recommended for :ref:`heap types ` to implement the vectorcall protocol. - When a user sets ``__call__`` in Python code, only ``tp_call`` is updated, - possibly making it inconsistent with the vectorcall function. + When a user sets :attr:`__call__` in Python code, only *tp_call* is updated, + likely making it inconsistent with the vectorcall function. .. note:: @@ -732,18 +721,19 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionchanged:: 3.8 - This slot was used for print formatting in Python 2.x. - In Python 3.0 to 3.7, it was reserved and named ``tp_print``. + Before version 3.8, this slot was named ``tp_print``. + In Python 2.x, it was used for printing to a file. + In Python 3.0 to 3.7, it was unused. **Inheritance:** - This field is inherited by subtypes together with - :c:member:`~PyTypeObject.tp_call`: a subtype inherits - :c:member:`~PyTypeObject.tp_vectorcall_offset` from its base type when - the subtype?s :c:member:`~PyTypeObject.tp_call` is ``NULL``. - - Note that `heap types`_ (including subclasses defined in Python) do not - inherit the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag. + This field is always inherited. + However, the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag is not + always inherited. If it's not, then the subclass won't use + :ref:`vectorcall `, except when + :c:func:`PyVectorcall_Call` is explicitly called. + This is in particular the case for `heap types`_ + (including subclasses defined in Python). .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -1171,18 +1161,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_finalize` slot is always present in the type structure. + .. data:: _Py_TPFLAGS_HAVE_VECTORCALL - This bit is set when the class implements the vectorcall protocol. + This bit is set when the class implements + the :ref:`vectorcall protocol `. See :c:member:`~PyTypeObject.tp_vectorcall_offset` for details. **Inheritance:** - This bit is set on *static* subtypes if ``tp_flags`` is not overridden: - a subtype inherits ``_Py_TPFLAGS_HAVE_VECTORCALL`` from its base type - when the subtype?s :c:member:`~PyTypeObject.tp_call` is ``NULL`` - and the subtype's ``Py_TPFLAGS_HEAPTYPE`` is not set. - + This bit is inherited for *static* subtypes if + :c:member:`~PyTypeObject.tp_call` is also inherited. `Heap types`_ do not inherit ``_Py_TPFLAGS_HAVE_VECTORCALL``. .. note:: @@ -1715,9 +1704,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds); - The subtype argument is the type of the object being created; the *args* and + The *subtype* argument is the type of the object being created; the *args* and *kwds* arguments represent positional and keyword arguments of the call to the - type. Note that subtype doesn't have to equal the type whose :c:member:`~PyTypeObject.tp_new` + type. Note that *subtype* doesn't have to equal the type whose :c:member:`~PyTypeObject.tp_new` function is called; it may be a subtype of that type (but not an unrelated type). @@ -1900,6 +1889,21 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. seealso:: "Safe object finalization" (:pep:`442`) +.. c:member:: vectorcallfunc PyTypeObject.tp_vectorcall + + Vectorcall function to use for calls of this type object. + In other words, it is used to implement + :ref:`vectorcall ` for ``type.__call__``. + If ``tp_vectorcall`` is ``NULL``, the default call implementation + using :attr:`__new__` and :attr:`__init__` is used. + + **Inheritance:** + + This field is never inherited. + + .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) + + The remaining fields are only defined if the feature test macro :const:`COUNT_ALLOCS` is defined, and are for internal use only. They are documented here for completeness. None of these fields are inherited by @@ -2369,14 +2373,6 @@ Slot Type typedefs .. c:type:: void (*destructor)(PyObject *) -.. c:type:: PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) - - See :c:member:`~PyTypeObject.tp_vectorcall_offset`. - - Arguments to ``vectorcallfunc`` are the same as for :c:func:`_PyObject_Vectorcall`. - - .. versionadded:: 3.8 - .. c:type:: void (*freefunc)(void *) See :c:member:`~PyTypeObject.tp_free`. diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 8338cb6cb4f4c..089095546fc72 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -347,20 +347,20 @@ See :pep:`587` for a full description. (Contributed by Victor Stinner in :issue:`36763`.) -Vectorcall: a fast calling protocol for CPython ------------------------------------------------ +PEP 590: Vectorcall: a fast calling protocol for CPython +-------------------------------------------------------- -The "vectorcall" protocol is added to the Python/C API. +:ref:`vectorcall` is added to the Python/C API. It is meant to formalize existing optimizations which were already done for various classes. -Any extension type implementing a callable can use this protocol. +Any static type implementing a callable can use this protocol. This is currently provisional. The aim is to make it fully public in Python 3.9. See :pep:`590` for a full description. -(Contributed by Jeroen Demeyer and Mark Shannon in :issue:`36974`.) +(Contributed by Jeroen Demeyer, Mark Shannon and Petr Viktorin in :issue:`36974`.) Pickle protocol 5 with out-of-band data buffers From webhook-mailer at python.org Tue Nov 12 08:34:24 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 13:34:24 -0000 Subject: [Python-checkins] [3.7] bpo-38421: Update email.utils documentation (GH-16678) (GH-17121) Message-ID: https://github.com/python/cpython/commit/eadddad6b093bca74601b1ea91ab96119bc543d8 commit: eadddad6b093bca74601b1ea91ab96119bc543d8 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T05:34:16-08:00 summary: [3.7] bpo-38421: Update email.utils documentation (GH-16678) (GH-17121) Updates documentation around email.utils.parsedate_tz(). Currently, the documentation specifies that when a string without a is timezone passed to parsedate_tz(), the last tuple is returned as ```None```. This is no longer true since Python 3.3 https://bugs.python.org/issue38421 (cherry picked from commit a12255d8def0c82560545e66c1be981a447751c3) Co-authored-by: David K https://bugs.python.org/issue38421 Automerge-Triggered-By: @encukou files: M Doc/library/email.utils.rst diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 63fae2ab84e21..4d0e920eb0ad2 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -117,8 +117,8 @@ of the new API. a 10-tuple; the first 9 elements make up a tuple that can be passed directly to :func:`time.mktime`, and the tenth is the offset of the date's timezone from UTC (which is the official term for Greenwich Mean Time) [#]_. If the input string - has no timezone, the last element of the tuple returned is ``None``. Note that - indexes 6, 7, and 8 of the result tuple are not usable. + has no timezone, the last element of the tuple returned is ``0``, which represents + UTC. Note that indexes 6, 7, and 8 of the result tuple are not usable. .. function:: parsedate_to_datetime(date) From webhook-mailer at python.org Tue Nov 12 08:34:28 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 13:34:28 -0000 Subject: [Python-checkins] [3.8] bpo-38421: Update email.utils documentation (GH-16678) (GH-17122) Message-ID: https://github.com/python/cpython/commit/29fd6a77d509cffacc5691ebd9dab53455ad959e commit: 29fd6a77d509cffacc5691ebd9dab53455ad959e branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T05:34:23-08:00 summary: [3.8] bpo-38421: Update email.utils documentation (GH-16678) (GH-17122) Updates documentation around email.utils.parsedate_tz(). Currently, the documentation specifies that when a string without a is timezone passed to parsedate_tz(), the last tuple is returned as ```None```. This is no longer true since Python 3.3 https://bugs.python.org/issue38421 (cherry picked from commit a12255d8def0c82560545e66c1be981a447751c3) Co-authored-by: David K https://bugs.python.org/issue38421 Automerge-Triggered-By: @encukou files: M Doc/library/email.utils.rst diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 63fae2ab84e21..4d0e920eb0ad2 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -117,8 +117,8 @@ of the new API. a 10-tuple; the first 9 elements make up a tuple that can be passed directly to :func:`time.mktime`, and the tenth is the offset of the date's timezone from UTC (which is the official term for Greenwich Mean Time) [#]_. If the input string - has no timezone, the last element of the tuple returned is ``None``. Note that - indexes 6, 7, and 8 of the result tuple are not usable. + has no timezone, the last element of the tuple returned is ``0``, which represents + UTC. Note that indexes 6, 7, and 8 of the result tuple are not usable. .. function:: parsedate_to_datetime(date) From webhook-mailer at python.org Tue Nov 12 09:57:12 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 12 Nov 2019 14:57:12 -0000 Subject: [Python-checkins] bpo-38738: Fix formatting of True and False. (GH-17083) Message-ID: https://github.com/python/cpython/commit/138ccbb02216ca086047c3139857fb44f3dab1f9 commit: 138ccbb02216ca086047c3139857fb44f3dab1f9 branch: master author: Serhiy Storchaka committer: GitHub date: 2019-11-12T16:57:03+02:00 summary: bpo-38738: Fix formatting of True and False. (GH-17083) * "Return true/false" is replaced with "Return ``True``/``False``" if the function actually returns a bool. * Fixed formatting of some True and False literals (now in monospace). * Replaced "True/False" with "true/false" if it can be not only bool. * Replaced some 1/0 with True/False if it corresponds the code. * "Returns " is replaced with "Return ". files: M Doc/library/asyncio-stream.rst M Doc/library/dataclasses.rst M Doc/library/dialog.rst M Doc/library/difflib.rst M Doc/library/doctest.rst M Doc/library/email.compat32-message.rst M Doc/library/email.errors.rst M Doc/library/email.message.rst M Doc/library/fileinput.rst M Doc/library/functions.rst M Doc/library/gc.rst M Doc/library/hashlib.rst M Doc/library/http.cookiejar.rst M Doc/library/importlib.rst M Doc/library/inspect.rst M Doc/library/ipaddress.rst M Doc/library/keyword.rst M Doc/library/logging.handlers.rst M Doc/library/logging.rst M Doc/library/lzma.rst M Doc/library/msvcrt.rst M Doc/library/optparse.rst M Doc/library/os.rst M Doc/library/parser.rst M Doc/library/platform.rst M Doc/library/sched.rst M Doc/library/ssl.rst M Doc/library/stdtypes.rst M Doc/library/stringprep.rst M Doc/library/sys.rst M Doc/library/threading.rst M Doc/library/tkinter.ttk.rst M Doc/library/token.rst M Doc/library/unittest.mock.rst M Doc/library/venv.rst M Doc/library/wsgiref.rst M Doc/library/xml.dom.rst M Doc/library/xml.etree.elementtree.rst M Doc/tools/susp-ignored.csv M Doc/whatsnew/3.8.rst M Lib/difflib.py M Lib/tkinter/__init__.py diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index bb899714a0ec0..b76ed379c7f4c 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -263,8 +263,8 @@ StreamWriter .. method:: can_write_eof() - Return *True* if the underlying transport supports - the :meth:`write_eof` method, *False* otherwise. + Return ``True`` if the underlying transport supports + the :meth:`write_eof` method, ``False`` otherwise. .. method:: write_eof() diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 9e0288290203d..71768abf80c47 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -153,7 +153,7 @@ Module-level decorators, classes, and functions method of the superclass will be used (if the superclass is :class:`object`, this means it will fall back to id-based hashing). - - ``frozen``: If true (the default is False), assigning to fields will + - ``frozen``: If true (the default is ``False``), assigning to fields will generate an exception. This emulates read-only frozen instances. If :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then :exc:`TypeError` is raised. See the discussion below. @@ -386,8 +386,8 @@ Module-level decorators, classes, and functions .. function:: is_dataclass(class_or_instance) - Returns True if its parameter is a dataclass or an instance of one, - otherwise returns False. + Return ``True`` if its parameter is a dataclass or an instance of one, + otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for ``not diff --git a/Doc/library/dialog.rst b/Doc/library/dialog.rst index 836f662963370..dc82a974ce095 100644 --- a/Doc/library/dialog.rst +++ b/Doc/library/dialog.rst @@ -73,7 +73,7 @@ listed below: | *defaultextension* - default extension to append to file (save dialogs) - | *multiple* - when True, selection of multiple items is allowed + | *multiple* - when true, selection of multiple items is allowed **Static factory functions** @@ -227,4 +227,4 @@ is the base class for dialogs defined in other supporting modules. .. seealso:: - Modules :mod:`tkinter.messagebox`, :ref:`tut-files` \ No newline at end of file + Modules :mod:`tkinter.messagebox`, :ref:`tut-files` diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index c2a19dc019bb3..ada311bc3a205 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -338,14 +338,14 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. function:: IS_LINE_JUNK(line) - Return true for ignorable lines. The line *line* is ignorable if *line* is + Return ``True`` for ignorable lines. The line *line* is ignorable if *line* is blank or contains a single ``'#'``, otherwise it is not ignorable. Used as a default for parameter *linejunk* in :func:`ndiff` in older versions. .. function:: IS_CHARACTER_JUNK(ch) - Return true for ignorable characters. The character *ch* is ignorable if *ch* + Return ``True`` for ignorable characters. The character *ch* is ignorable if *ch* is a space or tab, otherwise it is not ignorable. Used as a default for parameter *charjunk* in :func:`ndiff`. @@ -370,7 +370,7 @@ The :class:`SequenceMatcher` class has this constructor: Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the element is "junk" and should be ignored. Passing ``None`` for *isjunk* is - equivalent to passing ``lambda x: 0``; in other words, no elements are ignored. + equivalent to passing ``lambda x: False``; in other words, no elements are ignored. For example, pass:: lambda x: x in " \t" diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 7fc471fe2ab7d..a77322f83acbd 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1529,7 +1529,7 @@ OutputChecker objects A class used to check the whether the actual output from a doctest example matches the expected output. :class:`OutputChecker` defines two methods: - :meth:`check_output`, which compares a given pair of outputs, and returns true + :meth:`check_output`, which compares a given pair of outputs, and returns ``True`` if they match; and :meth:`output_difference`, which returns a string describing the differences between two outputs. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 09ea64a5a01aa..745b3a6a3ad42 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -308,7 +308,7 @@ Here are the methods of the :class:`Message` class: .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done case-insensitively and *name* should not include the trailing colon. Used for the ``in`` operator, e.g.:: diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 511ad16358319..f4b9f52509689 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -99,7 +99,7 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. * :class:`MultipartInvariantViolationDefect` -- A message claimed to be a :mimetype:`multipart`, but no subparts were found. Note that when a message has this defect, its :meth:`~email.message.Message.is_multipart` method may - return false even though its content type claims to be :mimetype:`multipart`. + return ``False`` even though its content type claims to be :mimetype:`multipart`. * :class:`InvalidBase64PaddingDefect` -- When decoding a block of base64 encoded bytes, the padding was not correct. Enough padding is added to diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index f1806a0866bb8..5e0509f418119 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -178,7 +178,7 @@ message objects. .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done without regard to case and *name* does not include the trailing colon. Used for the ``in`` operator. For example:: diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 8870c177fb1e1..236f5d563833e 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -109,14 +109,14 @@ if there is no active state, :exc:`RuntimeError` is raised. .. function:: isfirstline() - Returns true if the line just read is the first line of its file, otherwise - returns false. + Return ``True`` if the line just read is the first line of its file, otherwise + return ``False``. .. function:: isstdin() - Returns true if the last line was read from ``sys.stdin``, otherwise returns - false. + Return ``True`` if the last line was read from ``sys.stdin``, otherwise return + ``False``. .. function:: nextfile() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index acf922dcd1378..28b9649a16320 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -181,8 +181,8 @@ are always available. They are listed here in alphabetical order. .. function:: callable(object) Return :const:`True` if the *object* argument appears callable, - :const:`False` if not. If this returns true, it is still possible that a - call fails, but if it is false, calling *object* will never succeed. + :const:`False` if not. If this returns ``True``, it is still possible that a + call fails, but if it is ``False``, calling *object* will never succeed. Note that classes are callable (calling a class returns a new instance); instances are callable if their class has a :meth:`__call__` method. @@ -840,19 +840,19 @@ are always available. They are listed here in alphabetical order. .. function:: isinstance(object, classinfo) - Return true if the *object* argument is an instance of the *classinfo* + Return ``True`` if the *object* argument is an instance of the *classinfo* argument, or of a (direct, indirect or :term:`virtual `) subclass thereof. If *object* is not - an object of the given type, the function always returns false. + an object of the given type, the function always returns ``False``. If *classinfo* is a tuple of type objects (or recursively, other such - tuples), return true if *object* is an instance of any of the types. + tuples), return ``True`` if *object* is an instance of any of the types. If *classinfo* is not a type or tuple of types and such tuples, a :exc:`TypeError` exception is raised. .. function:: issubclass(class, classinfo) - Return true if *class* is a subclass (direct, indirect or :term:`virtual + Return ``True`` if *class* is a subclass (direct, indirect or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class objects, in which case every entry in *classinfo* will be checked. In any other diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 366861c524c3d..13eda917b9a80 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -35,7 +35,7 @@ The :mod:`gc` module provides the following functions: .. function:: isenabled() - Returns true if automatic collection is enabled. + Return ``True`` if automatic collection is enabled. .. function:: collect(generation=2) diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 6eb3a7bb4cc32..b737d22d4100c 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -82,8 +82,8 @@ library that Python uses on your platform. On most platforms the .. versionchanged:: 3.9 All hashlib constructors take a keyword-only argument *usedforsecurity* - with default value *True*. A false value allows the use of insecure and - blocked hashing algorithms in restricted environments. *False* indicates + with default value ``True``. A false value allows the use of insecure and + blocked hashing algorithms in restricted environments. ``False`` indicates that the hashing algorithm is not used in a security context, e.g. as a non-cryptographic one-way compression function. diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 1788bd8f833d1..9ac5d52a2ab09 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -378,7 +378,7 @@ methods: .. method:: CookiePolicy.domain_return_ok(domain, request) - Return false if cookies should not be returned, given cookie domain. + Return ``False`` if cookies should not be returned, given cookie domain. This method is an optimization. It removes the need for checking every cookie with a particular domain (which might involve reading many files). Returning @@ -402,7 +402,7 @@ methods: .. method:: CookiePolicy.path_return_ok(path, request) - Return false if cookies should not be returned, given cookie path. + Return ``False`` if cookies should not be returned, given cookie path. See the documentation for :meth:`domain_return_ok`. @@ -711,7 +711,7 @@ accessed using the following methods: .. method:: Cookie.has_nonstandard_attr(name) - Return true if cookie has the named cookie-attribute. + Return ``True`` if cookie has the named cookie-attribute. .. method:: Cookie.get_nonstandard_attr(name, default=None) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 54ca8b8b50a44..cfde3a47f75dc 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1168,7 +1168,7 @@ find and load modules. .. method:: is_package(fullname) - Return true if :attr:`path` appears to be for a package. + Return ``True`` if :attr:`path` appears to be for a package. .. method:: path_stats(path) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 2a71201a80b2c..f6156a0eb370c 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -277,55 +277,55 @@ attributes: .. function:: ismodule(object) - Return true if the object is a module. + Return ``True`` if the object is a module. .. function:: isclass(object) - Return true if the object is a class, whether built-in or created in Python + Return ``True`` if the object is a class, whether built-in or created in Python code. .. function:: ismethod(object) - Return true if the object is a bound method written in Python. + Return ``True`` if the object is a bound method written in Python. .. function:: isfunction(object) - Return true if the object is a Python function, which includes functions + Return ``True`` if the object is a Python function, which includes functions created by a :term:`lambda` expression. .. function:: isgeneratorfunction(object) - Return true if the object is a Python generator function. + Return ``True`` if the object is a Python generator function. .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a Python generator function. .. function:: isgenerator(object) - Return true if the object is a generator. + Return ``True`` if the object is a generator. .. function:: iscoroutinefunction(object) - Return true if the object is a :term:`coroutine function` + Return ``True`` if the object is a :term:`coroutine function` (a function defined with an :keyword:`async def` syntax). .. versionadded:: 3.5 .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`coroutine function`. .. function:: iscoroutine(object) - Return true if the object is a :term:`coroutine` created by an + Return ``True`` if the object is a :term:`coroutine` created by an :keyword:`async def` function. .. versionadded:: 3.5 @@ -333,7 +333,7 @@ attributes: .. function:: isawaitable(object) - Return true if the object can be used in :keyword:`await` expression. + Return ``True`` if the object can be used in :keyword:`await` expression. Can also be used to distinguish generator-based coroutines from regular generators:: @@ -352,7 +352,7 @@ attributes: .. function:: isasyncgenfunction(object) - Return true if the object is an :term:`asynchronous generator` function, + Return ``True`` if the object is an :term:`asynchronous generator` function, for example:: >>> async def agen(): @@ -364,50 +364,50 @@ attributes: .. versionadded:: 3.6 .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`asynchronous generator` function. .. function:: isasyncgen(object) - Return true if the object is an :term:`asynchronous generator iterator` + Return ``True`` if the object is an :term:`asynchronous generator iterator` created by an :term:`asynchronous generator` function. .. versionadded:: 3.6 .. function:: istraceback(object) - Return true if the object is a traceback. + Return ``True`` if the object is a traceback. .. function:: isframe(object) - Return true if the object is a frame. + Return ``True`` if the object is a frame. .. function:: iscode(object) - Return true if the object is a code. + Return ``True`` if the object is a code. .. function:: isbuiltin(object) - Return true if the object is a built-in function or a bound built-in method. + Return ``True`` if the object is a built-in function or a bound built-in method. .. function:: isroutine(object) - Return true if the object is a user-defined or built-in function or method. + Return ``True`` if the object is a user-defined or built-in function or method. .. function:: isabstract(object) - Return true if the object is an abstract base class. + Return ``True`` if the object is an abstract base class. .. function:: ismethoddescriptor(object) - Return true if the object is a method descriptor, but not if + Return ``True`` if the object is a method descriptor, but not if :func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin` are true. @@ -418,14 +418,14 @@ attributes: sensible, and :attr:`__doc__` often is. Methods implemented via descriptors that also pass one of the other tests - return false from the :func:`ismethoddescriptor` test, simply because the + return ``False`` from the :func:`ismethoddescriptor` test, simply because the other tests promise more -- you can, e.g., count on having the :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`. .. function:: isdatadescriptor(object) - Return true if the object is a data descriptor. + Return ``True`` if the object is a data descriptor. Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. Examples are properties (defined in Python), getsets, and members. The @@ -438,7 +438,7 @@ attributes: .. function:: isgetsetdescriptor(object) - Return true if the object is a getset descriptor. + Return ``True`` if the object is a getset descriptor. .. impl-detail:: @@ -449,7 +449,7 @@ attributes: .. function:: ismemberdescriptor(object) - Return true if the object is a member descriptor. + Return ``True`` if the object is a member descriptor. .. impl-detail:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index b7b502aff15e0..140401d2f3673 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -557,7 +557,7 @@ dictionaries. .. method:: subnet_of(other) - Returns *True* if this network is a subnet of *other*. + Return ``True`` if this network is a subnet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') @@ -568,7 +568,7 @@ dictionaries. .. method:: supernet_of(other) - Returns *True* if this network is a supernet of *other*. + Return ``True`` if this network is a supernet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') diff --git a/Doc/library/keyword.rst b/Doc/library/keyword.rst index 173db23544a47..3768df969c55c 100644 --- a/Doc/library/keyword.rst +++ b/Doc/library/keyword.rst @@ -13,7 +13,7 @@ This module allows a Python program to determine if a string is a keyword. .. function:: iskeyword(s) - Return true if *s* is a Python keyword. + Return ``True`` if *s* is a Python keyword. .. data:: kwlist diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index eccd0ae41da77..059ab3d3a3444 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -867,8 +867,8 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: emit(record) - Appends the record to the buffer. If :meth:`shouldFlush` returns true, - calls :meth:`flush` to process the buffer. + Append the record to the buffer. If :meth:`shouldFlush` returns true, + call :meth:`flush` to process the buffer. .. method:: flush() @@ -879,7 +879,7 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: shouldFlush(record) - Returns true if the buffer is up to capacity. This method can be + Return ``True`` if the buffer is up to capacity. This method can be overridden to implement custom flushing strategies. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 3ed24605db6fd..3b414ad30272c 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -294,7 +294,7 @@ is the module's name in the Python package namespace. .. method:: Logger.filter(record) - Applies this logger's filters to the record and returns a true value if the + Apply this logger's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be processed (passed to handlers). If one returns a false value, no @@ -447,7 +447,7 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call .. method:: Handler.filter(record) - Applies this handler's filters to the record and returns a true value if the + Apply this handler's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be emitted. If one returns a false value, the handler will not emit the diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index cce6c23e611e3..4bfff9c6147ed 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -313,7 +313,7 @@ Miscellaneous .. function:: is_check_supported(check) - Returns true if the given integrity check is supported on this system. + Return ``True`` if the given integrity check is supported on this system. :const:`CHECK_NONE` and :const:`CHECK_CRC32` are always supported. :const:`CHECK_CRC64` and :const:`CHECK_SHA256` may be unavailable if you are diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index bd34ffb1b2335..14ad2cd4373af 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -92,7 +92,7 @@ Console I/O .. function:: kbhit() - Return true if a keypress is waiting to be read. + Return ``True`` if a keypress is waiting to be read. .. function:: getch() diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 16f1cf008fff3..c1a18e0147431 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -928,10 +928,10 @@ The canonical way to create an :class:`Option` instance is with the store a constant value ``"store_true"`` - store a true value + store ``True`` ``"store_false"`` - store a false value + store ``False`` ``"append"`` append this option's argument to a list @@ -1135,12 +1135,12 @@ must specify for any option using that action. * ``"store_true"`` [relevant: :attr:`~Option.dest`] - A special case of ``"store_const"`` that stores a true value to + A special case of ``"store_const"`` that stores ``True`` to :attr:`~Option.dest`. * ``"store_false"`` [relevant: :attr:`~Option.dest`] - Like ``"store_true"``, but stores a false value. + Like ``"store_true"``, but stores ``False``. Example:: @@ -1396,7 +1396,7 @@ provides several methods to help you out: .. method:: OptionParser.has_option(opt_str) - Return true if the OptionParser has an option with option string *opt_str* + Return ``True`` if the OptionParser has an option with option string *opt_str* (e.g., ``-q`` or ``--verbose``). .. method:: OptionParser.remove_option(opt_str) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 48bd6b95a9b39..652d8de4e384f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -148,7 +148,7 @@ process and user. versa). :data:`environb` is only available if :data:`supports_bytes_environ` is - True. + ``True``. .. versionadded:: 3.2 @@ -236,7 +236,7 @@ process and user. *default* if it doesn't. *key*, *default* and the result are bytes. :func:`getenvb` is only available if :data:`supports_bytes_environ` - is True. + is ``True``. .. availability:: most flavors of Unix. diff --git a/Doc/library/parser.rst b/Doc/library/parser.rst index e4d6d1d0f5a3f..79fc10d0675af 100644 --- a/Doc/library/parser.rst +++ b/Doc/library/parser.rst @@ -234,8 +234,8 @@ determine if an ST was created from source code via :func:`expr` or .. index:: builtin: compile - When *st* represents an ``'eval'`` form, this function returns true, otherwise - it returns false. This is useful, since code objects normally cannot be queried + When *st* represents an ``'eval'`` form, this function returns ``True``, otherwise + it returns ``False``. This is useful, since code objects normally cannot be queried for this information using existing built-in functions. Note that the code objects created by :func:`compilest` cannot be queried like this either, and are identical to those created by the built-in :func:`compile` function. diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index e07f9d613a0d2..1d33afc75870a 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -226,8 +226,8 @@ Windows Platform .. function:: win32_is_iot() - Returns True if the windows edition returned by win32_edition is recognized - as an IoT edition. + Return ``True`` if the Windows edition returned by :func:`win32_edition` + is recognized as an IoT edition. .. versionadded:: 3.8 diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index fab16f52c4621..a4ba2848f11dd 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -104,7 +104,7 @@ Scheduler Objects .. method:: scheduler.empty() - Return true if the event queue is empty. + Return ``True`` if the event queue is empty. .. method:: scheduler.run(blocking=True) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 923bd87f2d7e4..e2c75bbd0a06c 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1658,7 +1658,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is - False. + ``False``. OpenSSL 1.1.0 to 1.1.0e will abort the handshake and raise :exc:`SSLError` when both sides support ALPN but cannot agree on a protocol. 1.1.0f+ @@ -1677,7 +1677,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_NPN` is - False. + ``False``. .. versionadded:: 3.3 diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index e8b3aba4b9097..b362cf5fa85e6 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1669,16 +1669,16 @@ expression support in the :mod:`re` module). .. method:: str.isalnum() - Return true if all characters in the string are alphanumeric and there is at - least one character, false otherwise. A character ``c`` is alphanumeric if one + Return ``True`` if all characters in the string are alphanumeric and there is at + least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or ``c.isnumeric()``. .. method:: str.isalpha() - Return true if all characters in the string are alphabetic and there is at least - one character, false otherwise. Alphabetic characters are those characters defined + Return ``True`` if all characters in the string are alphabetic and there is at least + one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the "Alphabetic" property defined in the Unicode Standard. @@ -1686,8 +1686,8 @@ expression support in the :mod:`re` module). .. method:: str.isascii() - Return true if the string is empty or all characters in the string are ASCII, - false otherwise. + Return ``True`` if the string is empty or all characters in the string are ASCII, + ``False`` otherwise. ASCII characters have code points in the range U+0000-U+007F. .. versionadded:: 3.7 @@ -1695,8 +1695,8 @@ expression support in the :mod:`re` module). .. method:: str.isdecimal() - Return true if all characters in the string are decimal - characters and there is at least one character, false + Return ``True`` if all characters in the string are decimal + characters and there is at least one character, ``False`` otherwise. Decimal characters are those that can be used to form numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in the Unicode @@ -1705,8 +1705,8 @@ expression support in the :mod:`re` module). .. method:: str.isdigit() - Return true if all characters in the string are digits and there is at least one - character, false otherwise. Digits include decimal characters and digits that need + Return ``True`` if all characters in the string are digits and there is at least one + character, ``False`` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the @@ -1715,7 +1715,7 @@ expression support in the :mod:`re` module). .. method:: str.isidentifier() - Return true if the string is a valid identifier according to the language + Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. Call :func:`keyword.iskeyword` to test whether string ``s`` is a reserved @@ -1734,14 +1734,14 @@ expression support in the :mod:`re` module). .. method:: str.islower() - Return true if all cased characters [4]_ in the string are lowercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are lowercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.isnumeric() - Return true if all characters in the string are numeric - characters, and there is at least one character, false + Return ``True`` if all characters in the string are numeric + characters, and there is at least one character, ``False`` otherwise. Numeric characters include digit characters, and all characters that have the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property @@ -1750,8 +1750,8 @@ expression support in the :mod:`re` module). .. method:: str.isprintable() - Return true if all characters in the string are printable or the string is - empty, false otherwise. Nonprintable characters are those characters defined + Return ``True`` if all characters in the string are printable or the string is + empty, ``False`` otherwise. Nonprintable characters are those characters defined in the Unicode character database as "Other" or "Separator", excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when @@ -1761,8 +1761,8 @@ expression support in the :mod:`re` module). .. method:: str.isspace() - Return true if there are only whitespace characters in the string and there is - at least one character, false otherwise. + Return ``True`` if there are only whitespace characters in the string and there is + at least one character, ``False`` otherwise. A character is *whitespace* if in the Unicode character database (see :mod:`unicodedata`), either its general category is ``Zs`` @@ -1772,15 +1772,15 @@ expression support in the :mod:`re` module). .. method:: str.istitle() - Return true if the string is a titlecased string and there is at least one + Return ``True`` if the string is a titlecased string and there is at least one character, for example uppercase characters may only follow uncased characters - and lowercase characters only cased ones. Return false otherwise. + and lowercase characters only cased ones. Return ``False`` otherwise. .. method:: str.isupper() - Return true if all cased characters [4]_ in the string are uppercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are uppercase and + there is at least one cased character, ``False`` otherwise. >>> 'BANANA'.isupper() True @@ -3010,8 +3010,8 @@ place, and instead produce new objects. .. method:: bytes.isalnum() bytearray.isalnum() - Return true if all bytes in the sequence are alphabetical ASCII characters - or ASCII decimal digits and the sequence is not empty, false otherwise. + Return ``True`` if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. @@ -3027,8 +3027,8 @@ place, and instead produce new objects. .. method:: bytes.isalpha() bytearray.isalpha() - Return true if all bytes in the sequence are alphabetic ASCII characters - and the sequence is not empty, false otherwise. Alphabetic ASCII + Return ``True`` if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. @@ -3043,8 +3043,8 @@ place, and instead produce new objects. .. method:: bytes.isascii() bytearray.isascii() - Return true if the sequence is empty or all bytes in the sequence are ASCII, - false otherwise. + Return ``True`` if the sequence is empty or all bytes in the sequence are ASCII, + ``False`` otherwise. ASCII bytes are in the range 0-0x7F. .. versionadded:: 3.7 @@ -3053,8 +3053,8 @@ place, and instead produce new objects. .. method:: bytes.isdigit() bytearray.isdigit() - Return true if all bytes in the sequence are ASCII decimal digits - and the sequence is not empty, false otherwise. ASCII decimal digits are + Return ``True`` if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, ``False`` otherwise. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. For example:: @@ -3068,8 +3068,8 @@ place, and instead produce new objects. .. method:: bytes.islower() bytearray.islower() - Return true if there is at least one lowercase ASCII character - in the sequence and no uppercase ASCII characters, false otherwise. + Return ``True`` if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, ``False`` otherwise. For example:: @@ -3086,8 +3086,8 @@ place, and instead produce new objects. .. method:: bytes.isspace() bytearray.isspace() - Return true if all bytes in the sequence are ASCII whitespace and the - sequence is not empty, false otherwise. ASCII whitespace characters are + Return ``True`` if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, ``False`` otherwise. ASCII whitespace characters are those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). @@ -3095,8 +3095,8 @@ place, and instead produce new objects. .. method:: bytes.istitle() bytearray.istitle() - Return true if the sequence is ASCII titlecase and the sequence is not - empty, false otherwise. See :meth:`bytes.title` for more details on the + Return ``True`` if the sequence is ASCII titlecase and the sequence is not + empty, ``False`` otherwise. See :meth:`bytes.title` for more details on the definition of "titlecase". For example:: @@ -3110,8 +3110,8 @@ place, and instead produce new objects. .. method:: bytes.isupper() bytearray.isupper() - Return true if there is at least one uppercase alphabetic ASCII character - in the sequence and no lowercase ASCII characters, false otherwise. + Return ``True`` if there is at least one uppercase alphabetic ASCII character + in the sequence and no lowercase ASCII characters, ``False`` otherwise. For example:: diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 330032ba1c0ba..5cfb533d802db 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -34,7 +34,7 @@ itself was generated using the ``mkstringprep.py`` utility. As a result, these tables are exposed as functions, not as data structures. There are two kinds of tables in the RFC: sets and mappings. For a set, :mod:`stringprep` provides the "characteristic function", i.e. a function that -returns true if the parameter is part of the set. For mappings, it provides the +returns ``True`` if the parameter is part of the set. For mappings, it provides the mapping function: given the key, it returns the associated value. Below is a list of all functions available in the module. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index a2e930b35d57f..4b0bcde4a8b49 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1414,7 +1414,7 @@ always available. On Windows, UTF-8 is used for the console device. Non-character devices such as disk files and pipes use the system locale encoding (i.e. the ANSI codepage). Non-console character - devices such as NUL (i.e. where isatty() returns True) use the + devices such as NUL (i.e. where ``isatty()`` returns ``True``) use the value of the console input and output codepages at startup, respectively for stdin and stdout/stderr. This defaults to the system locale encoding if the process is not initially attached diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 905862e7747fb..9a68491fbd53f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -543,15 +543,15 @@ Reentrant locks also support the :ref:`context management protocol ` There is no return value in this case. When invoked with the *blocking* argument set to true, do the same thing as when - called without arguments, and return true. + called without arguments, and return ``True``. When invoked with the *blocking* argument set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do the - same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do the + same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* - and as long as the lock cannot be acquired. Return true if the lock has + and as long as the lock cannot be acquired. Return ``True`` if the lock has been acquired, false if the timeout has elapsed. .. versionchanged:: 3.2 @@ -784,20 +784,20 @@ Semaphores also support the :ref:`context management protocol `. When invoked without arguments: * If the internal counter is larger than zero on entry, decrement it by - one and return true immediately. + one and return ``True`` immediately. * If the internal counter is zero on entry, block until awoken by a call to :meth:`~Semaphore.release`. Once awoken (and the counter is greater - than 0), decrement the counter by 1 and return true. Exactly one + than 0), decrement the counter by 1 and return ``True``. Exactly one thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. When invoked with *blocking* set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do - the same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do + the same thing as when called without arguments, and return ``True``. When invoked with a *timeout* other than ``None``, it will block for at most *timeout* seconds. If acquire does not complete successfully in - that interval, return false. Return true otherwise. + that interval, return ``False``. Return ``True`` otherwise. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -877,7 +877,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. method:: is_set() - Return true if and only if the internal flag is true. + Return ``True`` if and only if the internal flag is true. .. method:: set() @@ -901,7 +901,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. floating point number specifying a timeout for the operation in seconds (or fractions thereof). - This method returns true if and only if the internal flag has been set to + This method returns ``True`` if and only if the internal flag has been set to true, either before the wait call or after the wait starts, so it will always return ``True`` except if a timeout is given and the operation times out. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 5ba31feae1444..6967d7509657b 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -871,8 +871,8 @@ widget commands. | | remaining values are assumed empty. If there are more values | | | than columns, the extra values are ignored. | +--------+---------------------------------------------------------------+ - | open | True/False value indicating whether the item's children should| - | | be displayed or hidden. | + | open | ``True``/``False`` value indicating whether the item's | + | | children should be displayed or hidden. | +--------+---------------------------------------------------------------+ | tags | A list of tags associated with this item. | +--------+---------------------------------------------------------------+ @@ -997,7 +997,7 @@ ttk.Treeview The minimum width of the column in pixels. The treeview widget will not make the column any smaller than specified by this option when the widget is resized or the user drags a column. - * stretch: True/False + * stretch: ``True``/``False`` Specifies whether the column's width should be adjusted when the widget is resized. * width: width diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 5c641ef46d145..1777929be739d 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -29,17 +29,17 @@ functions. The functions mirror definitions in the Python C header files. .. function:: ISTERMINAL(x) - Return true for terminal token values. + Return ``True`` for terminal token values. .. function:: ISNONTERMINAL(x) - Return true for non-terminal token values. + Return ``True`` for non-terminal token values. .. function:: ISEOF(x) - Return true if *x* is the marker indicating the end of input. + Return ``True`` if *x* is the marker indicating the end of input. The token constants are: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 3fa3cfdaf21a3..746cf765b077f 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -360,7 +360,7 @@ the *new_callable* argument to :func:`patch`. assert the mock has been called with the specified calls. The :attr:`mock_calls` list is checked for the calls. - If *any_order* is false (the default) then the calls must be + If *any_order* is false then the calls must be sequential. There can be extra calls before or after the specified calls. @@ -1006,11 +1006,11 @@ object:: Assert the mock has been awaited with the specified calls. The :attr:`await_args_list` list is checked for the awaits. - If *any_order* is False (the default) then the awaits must be + If *any_order* is false then the awaits must be sequential. There can be extra calls before or after the specified awaits. - If *any_order* is True then the awaits can be in any order, but + If *any_order* is true then the awaits can be in any order, but they must all appear in :attr:`await_args_list`. >>> mock = AsyncMock() @@ -2085,20 +2085,20 @@ to change the default. Methods and their defaults: -* ``__lt__``: NotImplemented -* ``__gt__``: NotImplemented -* ``__le__``: NotImplemented -* ``__ge__``: NotImplemented -* ``__int__``: 1 -* ``__contains__``: False -* ``__len__``: 0 -* ``__iter__``: iter([]) -* ``__exit__``: False -* ``__aexit__``: False -* ``__complex__``: 1j -* ``__float__``: 1.0 -* ``__bool__``: True -* ``__index__``: 1 +* ``__lt__``: ``NotImplemented`` +* ``__gt__``: ``NotImplemented`` +* ``__le__``: ``NotImplemented`` +* ``__ge__``: ``NotImplemented`` +* ``__int__``: ``1`` +* ``__contains__``: ``False`` +* ``__len__``: ``0`` +* ``__iter__``: ``iter([])`` +* ``__exit__``: ``False`` +* ``__aexit__``: ``False`` +* ``__complex__``: ``1j`` +* ``__float__``: ``1.0`` +* ``__bool__``: ``True`` +* ``__index__``: ``1`` * ``__hash__``: default hash for the mock * ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index c674b02a7065a..b29fb3ebb60ea 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -281,9 +281,9 @@ subclass which installs setuptools and pip into a created virtual environment:: This builder installs setuptools and pip so that you can pip or easy_install other packages into the created virtual environment. - :param nodist: If True, setuptools and pip are not installed into the + :param nodist: If true, setuptools and pip are not installed into the created virtual environment. - :param nopip: If True, pip is not installed into the created + :param nopip: If true, pip is not installed into the created virtual environment. :param progress: If setuptools or pip are installed, the progress of the installation can be monitored by passing a progress diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 6edd0714b9df3..1e30aa4a898c1 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -144,7 +144,7 @@ also provides these miscellaneous utilities: .. function:: is_hop_by_hop(header_name) - Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by + Return ``True`` if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by :rfc:`2616`. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 18519a75a5461..98454e18ff1f8 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -210,7 +210,7 @@ DOM Level 2 added the ability to create new :class:`Document` and .. method:: DOMImplementation.hasFeature(feature, version) - Return true if the feature identified by the pair of strings *feature* and + Return ``True`` if the feature identified by the pair of strings *feature* and *version* is implemented. @@ -335,17 +335,17 @@ All of the components of an XML document are subclasses of :class:`Node`. .. method:: Node.hasAttributes() - Returns true if the node has any attributes. + Return ``True`` if the node has any attributes. .. method:: Node.hasChildNodes() - Returns true if the node has any child nodes. + Return ``True`` if the node has any child nodes. .. method:: Node.isSameNode(other) - Returns true if *other* refers to the same node as this node. This is especially + Return ``True`` if *other* refers to the same node as this node. This is especially useful for DOM implementations which use any sort of proxy architecture (because more than one object can refer to the same node). @@ -604,12 +604,12 @@ of that class. .. method:: Element.hasAttribute(name) - Returns true if the element has an attribute named by *name*. + Return ``True`` if the element has an attribute named by *name*. .. method:: Element.hasAttributeNS(namespaceURI, localName) - Returns true if the element has an attribute named by *namespaceURI* and + Return ``True`` if the element has an attribute named by *namespaceURI* and *localName*. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index abc15d44b2f65..658bc3a54f86e 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -586,8 +586,8 @@ Functions .. function:: iselement(element) - Checks if an object appears to be a valid element object. *element* is an - element instance. Returns a true value if this is an element object. + Check if an object appears to be a valid element object. *element* is an + element instance. Return ``True`` if this is an element object. .. function:: iterparse(source, events=None, parser=None) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index fe15aae796fe6..7615f24e6cf16 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -240,9 +240,9 @@ library/urllib.request,,:password,"""joe:password at python.org""" library/urllib.parse,,:scheme, library/urllib.parse,,:scheme,URL:scheme://host/path library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the" +library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If True, pip is not installed into the created" +library/venv,,:param,":param nopip: If true, pip is not installed into the created" library/venv,,:param,:param context: The information for the virtual environment library/xmlrpc.client,,:nil,ex:nil library/xmlrpc.client,,:pass,http://user:pass at host:port/path diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 089095546fc72..c71c1ab6fd181 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -924,7 +924,7 @@ logging ------- Added a *force* keyword argument to :func:`logging.basicConfig()` -When set to *True*, any existing handlers attached +When set to true, any existing handlers attached to the root logger are removed and closed before carrying out the configuration specified by the other arguments. @@ -1051,7 +1051,7 @@ environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. (Contributed by Anthony Sottile in :issue:`36264`.) -:func:`~os.path.isdir` on Windows no longer returns true for a link to a +:func:`~os.path.isdir` on Windows no longer returns ``True`` for a link to a non-existent directory. :func:`~os.path.realpath` on Windows now resolves reparse points, including @@ -1100,12 +1100,12 @@ pprint The :mod:`pprint` module added a *sort_dicts* parameter to several functions. By default, those functions continue to sort dictionaries before rendering or -printing. However, if *sort_dicts* is set to *False*, the dictionaries retain +printing. However, if *sort_dicts* is set to false, the dictionaries retain the order that keys were inserted. This can be useful for comparison to JSON inputs during debugging. In addition, there is a convenience new function, :func:`pprint.pp` that is -like :func:`pprint.pprint` but with *sort_dicts* defaulting to *False*:: +like :func:`pprint.pprint` but with *sort_dicts* defaulting to ``False``:: >>> from pprint import pprint, pp >>> d = dict(source='input.txt', operation='filter', destination='output.txt') diff --git a/Lib/difflib.py b/Lib/difflib.py index 3de1b3d0fcdfe..5d756436a67e1 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1074,7 +1074,7 @@ def _qformat(self, aline, bline, atags, btags): def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): r""" - Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + Return True for ignorable line: iff `line` is blank or contains a single '#'. Examples: @@ -1090,7 +1090,7 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): def IS_CHARACTER_JUNK(ch, ws=" \t"): r""" - Return 1 for ignorable character: iff `ch` is a space or tab. + Return True for ignorable character: iff `ch` is a space or tab. Examples: diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 5d5cf90e0bddc..a3378d012fb41 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1053,7 +1053,7 @@ def winfo_class(self): return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): - """Return true if at the last color request the colormap was full.""" + """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) @@ -3226,7 +3226,7 @@ def selection_clear(self, first, last=None): select_clear = selection_clear def selection_includes(self, index): - """Return 1 if INDEX is part of the selection.""" + """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) From webhook-mailer at python.org Tue Nov 12 11:54:31 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 12 Nov 2019 16:54:31 -0000 Subject: [Python-checkins] [3.8] bpo-38738: Fix formatting of True and False. (GH-17083) (GH-17125) Message-ID: https://github.com/python/cpython/commit/d360346640e19231032b072216195484fa2450b4 commit: d360346640e19231032b072216195484fa2450b4 branch: 3.8 author: Serhiy Storchaka committer: GitHub date: 2019-11-12T18:54:10+02:00 summary: [3.8] bpo-38738: Fix formatting of True and False. (GH-17083) (GH-17125) * "Return true/false" is replaced with "Return ``True``/``False``" if the function actually returns a bool. * Fixed formatting of some True and False literals (now in monospace). * Replaced "True/False" with "true/false" if it can be not only bool. * Replaced some 1/0 with True/False if it corresponds the code. * "Returns " is replaced with "Return ". (cherry picked from commit 138ccbb02216ca086047c3139857fb44f3dab1f9) files: M Doc/library/asyncio-stream.rst M Doc/library/dataclasses.rst M Doc/library/difflib.rst M Doc/library/doctest.rst M Doc/library/email.compat32-message.rst M Doc/library/email.errors.rst M Doc/library/email.message.rst M Doc/library/fileinput.rst M Doc/library/functions.rst M Doc/library/gc.rst M Doc/library/http.cookiejar.rst M Doc/library/importlib.rst M Doc/library/inspect.rst M Doc/library/ipaddress.rst M Doc/library/keyword.rst M Doc/library/logging.handlers.rst M Doc/library/logging.rst M Doc/library/lzma.rst M Doc/library/msvcrt.rst M Doc/library/optparse.rst M Doc/library/os.rst M Doc/library/parser.rst M Doc/library/platform.rst M Doc/library/sched.rst M Doc/library/ssl.rst M Doc/library/stdtypes.rst M Doc/library/stringprep.rst M Doc/library/sys.rst M Doc/library/threading.rst M Doc/library/tkinter.ttk.rst M Doc/library/token.rst M Doc/library/unittest.mock.rst M Doc/library/venv.rst M Doc/library/wsgiref.rst M Doc/library/xml.dom.rst M Doc/library/xml.etree.elementtree.rst M Doc/tools/susp-ignored.csv M Doc/whatsnew/3.8.rst M Lib/difflib.py M Lib/tkinter/__init__.py diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index bb899714a0ec0..b76ed379c7f4c 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -263,8 +263,8 @@ StreamWriter .. method:: can_write_eof() - Return *True* if the underlying transport supports - the :meth:`write_eof` method, *False* otherwise. + Return ``True`` if the underlying transport supports + the :meth:`write_eof` method, ``False`` otherwise. .. method:: write_eof() diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index db5c3e0c7e289..9aa4a19d57ac7 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -153,7 +153,7 @@ Module-level decorators, classes, and functions method of the superclass will be used (if the superclass is :class:`object`, this means it will fall back to id-based hashing). - - ``frozen``: If true (the default is False), assigning to fields will + - ``frozen``: If true (the default is ``False``), assigning to fields will generate an exception. This emulates read-only frozen instances. If :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then :exc:`TypeError` is raised. See the discussion below. @@ -386,8 +386,8 @@ Module-level decorators, classes, and functions .. function:: is_dataclass(class_or_instance) - Returns True if its parameter is a dataclass or an instance of one, - otherwise returns False. + Return ``True`` if its parameter is a dataclass or an instance of one, + otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for ``not diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index c2a19dc019bb3..ada311bc3a205 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -338,14 +338,14 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. function:: IS_LINE_JUNK(line) - Return true for ignorable lines. The line *line* is ignorable if *line* is + Return ``True`` for ignorable lines. The line *line* is ignorable if *line* is blank or contains a single ``'#'``, otherwise it is not ignorable. Used as a default for parameter *linejunk* in :func:`ndiff` in older versions. .. function:: IS_CHARACTER_JUNK(ch) - Return true for ignorable characters. The character *ch* is ignorable if *ch* + Return ``True`` for ignorable characters. The character *ch* is ignorable if *ch* is a space or tab, otherwise it is not ignorable. Used as a default for parameter *charjunk* in :func:`ndiff`. @@ -370,7 +370,7 @@ The :class:`SequenceMatcher` class has this constructor: Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the element is "junk" and should be ignored. Passing ``None`` for *isjunk* is - equivalent to passing ``lambda x: 0``; in other words, no elements are ignored. + equivalent to passing ``lambda x: False``; in other words, no elements are ignored. For example, pass:: lambda x: x in " \t" diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 7fc471fe2ab7d..a77322f83acbd 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1529,7 +1529,7 @@ OutputChecker objects A class used to check the whether the actual output from a doctest example matches the expected output. :class:`OutputChecker` defines two methods: - :meth:`check_output`, which compares a given pair of outputs, and returns true + :meth:`check_output`, which compares a given pair of outputs, and returns ``True`` if they match; and :meth:`output_difference`, which returns a string describing the differences between two outputs. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 09ea64a5a01aa..745b3a6a3ad42 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -308,7 +308,7 @@ Here are the methods of the :class:`Message` class: .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done case-insensitively and *name* should not include the trailing colon. Used for the ``in`` operator, e.g.:: diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 511ad16358319..f4b9f52509689 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -99,7 +99,7 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. * :class:`MultipartInvariantViolationDefect` -- A message claimed to be a :mimetype:`multipart`, but no subparts were found. Note that when a message has this defect, its :meth:`~email.message.Message.is_multipart` method may - return false even though its content type claims to be :mimetype:`multipart`. + return ``False`` even though its content type claims to be :mimetype:`multipart`. * :class:`InvalidBase64PaddingDefect` -- When decoding a block of base64 encoded bytes, the padding was not correct. Enough padding is added to diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index f1806a0866bb8..5e0509f418119 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -178,7 +178,7 @@ message objects. .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done without regard to case and *name* does not include the trailing colon. Used for the ``in`` operator. For example:: diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index f5e5280a13639..cc4039a30e38a 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -109,14 +109,14 @@ if there is no active state, :exc:`RuntimeError` is raised. .. function:: isfirstline() - Returns true if the line just read is the first line of its file, otherwise - returns false. + Return ``True`` if the line just read is the first line of its file, otherwise + return ``False``. .. function:: isstdin() - Returns true if the last line was read from ``sys.stdin``, otherwise returns - false. + Return ``True`` if the last line was read from ``sys.stdin``, otherwise return + ``False``. .. function:: nextfile() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index bc46844246cf0..ca2a039ea43d7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -181,8 +181,8 @@ are always available. They are listed here in alphabetical order. .. function:: callable(object) Return :const:`True` if the *object* argument appears callable, - :const:`False` if not. If this returns true, it is still possible that a - call fails, but if it is false, calling *object* will never succeed. + :const:`False` if not. If this returns ``True``, it is still possible that a + call fails, but if it is ``False``, calling *object* will never succeed. Note that classes are callable (calling a class returns a new instance); instances are callable if their class has a :meth:`__call__` method. @@ -838,19 +838,19 @@ are always available. They are listed here in alphabetical order. .. function:: isinstance(object, classinfo) - Return true if the *object* argument is an instance of the *classinfo* + Return ``True`` if the *object* argument is an instance of the *classinfo* argument, or of a (direct, indirect or :term:`virtual `) subclass thereof. If *object* is not - an object of the given type, the function always returns false. + an object of the given type, the function always returns ``False``. If *classinfo* is a tuple of type objects (or recursively, other such - tuples), return true if *object* is an instance of any of the types. + tuples), return ``True`` if *object* is an instance of any of the types. If *classinfo* is not a type or tuple of types and such tuples, a :exc:`TypeError` exception is raised. .. function:: issubclass(class, classinfo) - Return true if *class* is a subclass (direct, indirect or :term:`virtual + Return ``True`` if *class* is a subclass (direct, indirect or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class objects, in which case every entry in *classinfo* will be checked. In any other diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 366861c524c3d..13eda917b9a80 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -35,7 +35,7 @@ The :mod:`gc` module provides the following functions: .. function:: isenabled() - Returns true if automatic collection is enabled. + Return ``True`` if automatic collection is enabled. .. function:: collect(generation=2) diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 1788bd8f833d1..9ac5d52a2ab09 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -378,7 +378,7 @@ methods: .. method:: CookiePolicy.domain_return_ok(domain, request) - Return false if cookies should not be returned, given cookie domain. + Return ``False`` if cookies should not be returned, given cookie domain. This method is an optimization. It removes the need for checking every cookie with a particular domain (which might involve reading many files). Returning @@ -402,7 +402,7 @@ methods: .. method:: CookiePolicy.path_return_ok(path, request) - Return false if cookies should not be returned, given cookie path. + Return ``False`` if cookies should not be returned, given cookie path. See the documentation for :meth:`domain_return_ok`. @@ -711,7 +711,7 @@ accessed using the following methods: .. method:: Cookie.has_nonstandard_attr(name) - Return true if cookie has the named cookie-attribute. + Return ``True`` if cookie has the named cookie-attribute. .. method:: Cookie.get_nonstandard_attr(name, default=None) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 47e3dd03a687a..aa22a5b16838b 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1168,7 +1168,7 @@ find and load modules. .. method:: is_package(fullname) - Return true if :attr:`path` appears to be for a package. + Return ``True`` if :attr:`path` appears to be for a package. .. method:: path_stats(path) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 2a71201a80b2c..f6156a0eb370c 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -277,55 +277,55 @@ attributes: .. function:: ismodule(object) - Return true if the object is a module. + Return ``True`` if the object is a module. .. function:: isclass(object) - Return true if the object is a class, whether built-in or created in Python + Return ``True`` if the object is a class, whether built-in or created in Python code. .. function:: ismethod(object) - Return true if the object is a bound method written in Python. + Return ``True`` if the object is a bound method written in Python. .. function:: isfunction(object) - Return true if the object is a Python function, which includes functions + Return ``True`` if the object is a Python function, which includes functions created by a :term:`lambda` expression. .. function:: isgeneratorfunction(object) - Return true if the object is a Python generator function. + Return ``True`` if the object is a Python generator function. .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a Python generator function. .. function:: isgenerator(object) - Return true if the object is a generator. + Return ``True`` if the object is a generator. .. function:: iscoroutinefunction(object) - Return true if the object is a :term:`coroutine function` + Return ``True`` if the object is a :term:`coroutine function` (a function defined with an :keyword:`async def` syntax). .. versionadded:: 3.5 .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`coroutine function`. .. function:: iscoroutine(object) - Return true if the object is a :term:`coroutine` created by an + Return ``True`` if the object is a :term:`coroutine` created by an :keyword:`async def` function. .. versionadded:: 3.5 @@ -333,7 +333,7 @@ attributes: .. function:: isawaitable(object) - Return true if the object can be used in :keyword:`await` expression. + Return ``True`` if the object can be used in :keyword:`await` expression. Can also be used to distinguish generator-based coroutines from regular generators:: @@ -352,7 +352,7 @@ attributes: .. function:: isasyncgenfunction(object) - Return true if the object is an :term:`asynchronous generator` function, + Return ``True`` if the object is an :term:`asynchronous generator` function, for example:: >>> async def agen(): @@ -364,50 +364,50 @@ attributes: .. versionadded:: 3.6 .. versionchanged:: 3.8 - Functions wrapped in :func:`functools.partial` now return true if the + Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`asynchronous generator` function. .. function:: isasyncgen(object) - Return true if the object is an :term:`asynchronous generator iterator` + Return ``True`` if the object is an :term:`asynchronous generator iterator` created by an :term:`asynchronous generator` function. .. versionadded:: 3.6 .. function:: istraceback(object) - Return true if the object is a traceback. + Return ``True`` if the object is a traceback. .. function:: isframe(object) - Return true if the object is a frame. + Return ``True`` if the object is a frame. .. function:: iscode(object) - Return true if the object is a code. + Return ``True`` if the object is a code. .. function:: isbuiltin(object) - Return true if the object is a built-in function or a bound built-in method. + Return ``True`` if the object is a built-in function or a bound built-in method. .. function:: isroutine(object) - Return true if the object is a user-defined or built-in function or method. + Return ``True`` if the object is a user-defined or built-in function or method. .. function:: isabstract(object) - Return true if the object is an abstract base class. + Return ``True`` if the object is an abstract base class. .. function:: ismethoddescriptor(object) - Return true if the object is a method descriptor, but not if + Return ``True`` if the object is a method descriptor, but not if :func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin` are true. @@ -418,14 +418,14 @@ attributes: sensible, and :attr:`__doc__` often is. Methods implemented via descriptors that also pass one of the other tests - return false from the :func:`ismethoddescriptor` test, simply because the + return ``False`` from the :func:`ismethoddescriptor` test, simply because the other tests promise more -- you can, e.g., count on having the :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`. .. function:: isdatadescriptor(object) - Return true if the object is a data descriptor. + Return ``True`` if the object is a data descriptor. Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. Examples are properties (defined in Python), getsets, and members. The @@ -438,7 +438,7 @@ attributes: .. function:: isgetsetdescriptor(object) - Return true if the object is a getset descriptor. + Return ``True`` if the object is a getset descriptor. .. impl-detail:: @@ -449,7 +449,7 @@ attributes: .. function:: ismemberdescriptor(object) - Return true if the object is a member descriptor. + Return ``True`` if the object is a member descriptor. .. impl-detail:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index b7b502aff15e0..140401d2f3673 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -557,7 +557,7 @@ dictionaries. .. method:: subnet_of(other) - Returns *True* if this network is a subnet of *other*. + Return ``True`` if this network is a subnet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') @@ -568,7 +568,7 @@ dictionaries. .. method:: supernet_of(other) - Returns *True* if this network is a supernet of *other*. + Return ``True`` if this network is a supernet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') diff --git a/Doc/library/keyword.rst b/Doc/library/keyword.rst index 173db23544a47..3768df969c55c 100644 --- a/Doc/library/keyword.rst +++ b/Doc/library/keyword.rst @@ -13,7 +13,7 @@ This module allows a Python program to determine if a string is a keyword. .. function:: iskeyword(s) - Return true if *s* is a Python keyword. + Return ``True`` if *s* is a Python keyword. .. data:: kwlist diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 0e9870408ff43..fa0424dcd18f5 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -846,8 +846,8 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: emit(record) - Appends the record to the buffer. If :meth:`shouldFlush` returns true, - calls :meth:`flush` to process the buffer. + Append the record to the buffer. If :meth:`shouldFlush` returns true, + call :meth:`flush` to process the buffer. .. method:: flush() @@ -858,7 +858,7 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: shouldFlush(record) - Returns true if the buffer is up to capacity. This method can be + Return ``True`` if the buffer is up to capacity. This method can be overridden to implement custom flushing strategies. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 0fe2158ef06fa..4da5778fa6416 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -294,7 +294,7 @@ is the module's name in the Python package namespace. .. method:: Logger.filter(record) - Applies this logger's filters to the record and returns a true value if the + Apply this logger's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be processed (passed to handlers). If one returns a false value, no @@ -447,7 +447,7 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call .. method:: Handler.filter(record) - Applies this handler's filters to the record and returns a true value if the + Apply this handler's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be emitted. If one returns a false value, the handler will not emit the diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index cce6c23e611e3..4bfff9c6147ed 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -313,7 +313,7 @@ Miscellaneous .. function:: is_check_supported(check) - Returns true if the given integrity check is supported on this system. + Return ``True`` if the given integrity check is supported on this system. :const:`CHECK_NONE` and :const:`CHECK_CRC32` are always supported. :const:`CHECK_CRC64` and :const:`CHECK_SHA256` may be unavailable if you are diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index bd34ffb1b2335..14ad2cd4373af 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -92,7 +92,7 @@ Console I/O .. function:: kbhit() - Return true if a keypress is waiting to be read. + Return ``True`` if a keypress is waiting to be read. .. function:: getch() diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 16f1cf008fff3..c1a18e0147431 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -928,10 +928,10 @@ The canonical way to create an :class:`Option` instance is with the store a constant value ``"store_true"`` - store a true value + store ``True`` ``"store_false"`` - store a false value + store ``False`` ``"append"`` append this option's argument to a list @@ -1135,12 +1135,12 @@ must specify for any option using that action. * ``"store_true"`` [relevant: :attr:`~Option.dest`] - A special case of ``"store_const"`` that stores a true value to + A special case of ``"store_const"`` that stores ``True`` to :attr:`~Option.dest`. * ``"store_false"`` [relevant: :attr:`~Option.dest`] - Like ``"store_true"``, but stores a false value. + Like ``"store_true"``, but stores ``False``. Example:: @@ -1396,7 +1396,7 @@ provides several methods to help you out: .. method:: OptionParser.has_option(opt_str) - Return true if the OptionParser has an option with option string *opt_str* + Return ``True`` if the OptionParser has an option with option string *opt_str* (e.g., ``-q`` or ``--verbose``). .. method:: OptionParser.remove_option(opt_str) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 67fe36b54e2f8..e3f8977f9d076 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -148,7 +148,7 @@ process and user. versa). :data:`environb` is only available if :data:`supports_bytes_environ` is - True. + ``True``. .. versionadded:: 3.2 @@ -236,7 +236,7 @@ process and user. *default* if it doesn't. *key*, *default* and the result are bytes. :func:`getenvb` is only available if :data:`supports_bytes_environ` - is True. + is ``True``. .. availability:: most flavors of Unix. diff --git a/Doc/library/parser.rst b/Doc/library/parser.rst index 1d2da300709c8..7b380c367028c 100644 --- a/Doc/library/parser.rst +++ b/Doc/library/parser.rst @@ -234,8 +234,8 @@ determine if an ST was created from source code via :func:`expr` or .. index:: builtin: compile - When *st* represents an ``'eval'`` form, this function returns true, otherwise - it returns false. This is useful, since code objects normally cannot be queried + When *st* represents an ``'eval'`` form, this function returns ``True``, otherwise + it returns ``False``. This is useful, since code objects normally cannot be queried for this information using existing built-in functions. Note that the code objects created by :func:`compilest` cannot be queried like this either, and are identical to those created by the built-in :func:`compile` function. diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index e07f9d613a0d2..1d33afc75870a 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -226,8 +226,8 @@ Windows Platform .. function:: win32_is_iot() - Returns True if the windows edition returned by win32_edition is recognized - as an IoT edition. + Return ``True`` if the Windows edition returned by :func:`win32_edition` + is recognized as an IoT edition. .. versionadded:: 3.8 diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index fab16f52c4621..a4ba2848f11dd 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -104,7 +104,7 @@ Scheduler Objects .. method:: scheduler.empty() - Return true if the event queue is empty. + Return ``True`` if the event queue is empty. .. method:: scheduler.run(blocking=True) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 633e68ae273f7..f8fa25df6c241 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1658,7 +1658,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is - False. + ``False``. OpenSSL 1.1.0 to 1.1.0e will abort the handshake and raise :exc:`SSLError` when both sides support ALPN but cannot agree on a protocol. 1.1.0f+ @@ -1677,7 +1677,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_NPN` is - False. + ``False``. .. versionadded:: 3.3 diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 9bc4cbe4f7bc6..ceb562faaafbd 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1662,16 +1662,16 @@ expression support in the :mod:`re` module). .. method:: str.isalnum() - Return true if all characters in the string are alphanumeric and there is at - least one character, false otherwise. A character ``c`` is alphanumeric if one + Return ``True`` if all characters in the string are alphanumeric and there is at + least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or ``c.isnumeric()``. .. method:: str.isalpha() - Return true if all characters in the string are alphabetic and there is at least - one character, false otherwise. Alphabetic characters are those characters defined + Return ``True`` if all characters in the string are alphabetic and there is at least + one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the "Alphabetic" property defined in the Unicode Standard. @@ -1679,8 +1679,8 @@ expression support in the :mod:`re` module). .. method:: str.isascii() - Return true if the string is empty or all characters in the string are ASCII, - false otherwise. + Return ``True`` if the string is empty or all characters in the string are ASCII, + ``False`` otherwise. ASCII characters have code points in the range U+0000-U+007F. .. versionadded:: 3.7 @@ -1688,8 +1688,8 @@ expression support in the :mod:`re` module). .. method:: str.isdecimal() - Return true if all characters in the string are decimal - characters and there is at least one character, false + Return ``True`` if all characters in the string are decimal + characters and there is at least one character, ``False`` otherwise. Decimal characters are those that can be used to form numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in the Unicode @@ -1698,8 +1698,8 @@ expression support in the :mod:`re` module). .. method:: str.isdigit() - Return true if all characters in the string are digits and there is at least one - character, false otherwise. Digits include decimal characters and digits that need + Return ``True`` if all characters in the string are digits and there is at least one + character, ``False`` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the @@ -1708,7 +1708,7 @@ expression support in the :mod:`re` module). .. method:: str.isidentifier() - Return true if the string is a valid identifier according to the language + Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. Call :func:`keyword.iskeyword` to test whether string ``s`` is a reserved @@ -1727,14 +1727,14 @@ expression support in the :mod:`re` module). .. method:: str.islower() - Return true if all cased characters [4]_ in the string are lowercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are lowercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.isnumeric() - Return true if all characters in the string are numeric - characters, and there is at least one character, false + Return ``True`` if all characters in the string are numeric + characters, and there is at least one character, ``False`` otherwise. Numeric characters include digit characters, and all characters that have the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property @@ -1743,8 +1743,8 @@ expression support in the :mod:`re` module). .. method:: str.isprintable() - Return true if all characters in the string are printable or the string is - empty, false otherwise. Nonprintable characters are those characters defined + Return ``True`` if all characters in the string are printable or the string is + empty, ``False`` otherwise. Nonprintable characters are those characters defined in the Unicode character database as "Other" or "Separator", excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when @@ -1754,8 +1754,8 @@ expression support in the :mod:`re` module). .. method:: str.isspace() - Return true if there are only whitespace characters in the string and there is - at least one character, false otherwise. + Return ``True`` if there are only whitespace characters in the string and there is + at least one character, ``False`` otherwise. A character is *whitespace* if in the Unicode character database (see :mod:`unicodedata`), either its general category is ``Zs`` @@ -1765,15 +1765,15 @@ expression support in the :mod:`re` module). .. method:: str.istitle() - Return true if the string is a titlecased string and there is at least one + Return ``True`` if the string is a titlecased string and there is at least one character, for example uppercase characters may only follow uncased characters - and lowercase characters only cased ones. Return false otherwise. + and lowercase characters only cased ones. Return ``False`` otherwise. .. method:: str.isupper() - Return true if all cased characters [4]_ in the string are uppercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are uppercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.join(iterable) @@ -2986,8 +2986,8 @@ place, and instead produce new objects. .. method:: bytes.isalnum() bytearray.isalnum() - Return true if all bytes in the sequence are alphabetical ASCII characters - or ASCII decimal digits and the sequence is not empty, false otherwise. + Return ``True`` if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. @@ -3003,8 +3003,8 @@ place, and instead produce new objects. .. method:: bytes.isalpha() bytearray.isalpha() - Return true if all bytes in the sequence are alphabetic ASCII characters - and the sequence is not empty, false otherwise. Alphabetic ASCII + Return ``True`` if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. @@ -3019,8 +3019,8 @@ place, and instead produce new objects. .. method:: bytes.isascii() bytearray.isascii() - Return true if the sequence is empty or all bytes in the sequence are ASCII, - false otherwise. + Return ``True`` if the sequence is empty or all bytes in the sequence are ASCII, + ``False`` otherwise. ASCII bytes are in the range 0-0x7F. .. versionadded:: 3.7 @@ -3029,8 +3029,8 @@ place, and instead produce new objects. .. method:: bytes.isdigit() bytearray.isdigit() - Return true if all bytes in the sequence are ASCII decimal digits - and the sequence is not empty, false otherwise. ASCII decimal digits are + Return ``True`` if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, ``False`` otherwise. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. For example:: @@ -3044,8 +3044,8 @@ place, and instead produce new objects. .. method:: bytes.islower() bytearray.islower() - Return true if there is at least one lowercase ASCII character - in the sequence and no uppercase ASCII characters, false otherwise. + Return ``True`` if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, ``False`` otherwise. For example:: @@ -3062,8 +3062,8 @@ place, and instead produce new objects. .. method:: bytes.isspace() bytearray.isspace() - Return true if all bytes in the sequence are ASCII whitespace and the - sequence is not empty, false otherwise. ASCII whitespace characters are + Return ``True`` if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, ``False`` otherwise. ASCII whitespace characters are those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). @@ -3071,8 +3071,8 @@ place, and instead produce new objects. .. method:: bytes.istitle() bytearray.istitle() - Return true if the sequence is ASCII titlecase and the sequence is not - empty, false otherwise. See :meth:`bytes.title` for more details on the + Return ``True`` if the sequence is ASCII titlecase and the sequence is not + empty, ``False`` otherwise. See :meth:`bytes.title` for more details on the definition of "titlecase". For example:: @@ -3086,8 +3086,8 @@ place, and instead produce new objects. .. method:: bytes.isupper() bytearray.isupper() - Return true if there is at least one uppercase alphabetic ASCII character - in the sequence and no lowercase ASCII characters, false otherwise. + Return ``True`` if there is at least one uppercase alphabetic ASCII character + in the sequence and no lowercase ASCII characters, ``False`` otherwise. For example:: diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 330032ba1c0ba..5cfb533d802db 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -34,7 +34,7 @@ itself was generated using the ``mkstringprep.py`` utility. As a result, these tables are exposed as functions, not as data structures. There are two kinds of tables in the RFC: sets and mappings. For a set, :mod:`stringprep` provides the "characteristic function", i.e. a function that -returns true if the parameter is part of the set. For mappings, it provides the +returns ``True`` if the parameter is part of the set. For mappings, it provides the mapping function: given the key, it returns the associated value. Below is a list of all functions available in the module. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 34b808406866b..0e15467cb1a34 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1437,7 +1437,7 @@ always available. On Windows, UTF-8 is used for the console device. Non-character devices such as disk files and pipes use the system locale encoding (i.e. the ANSI codepage). Non-console character - devices such as NUL (i.e. where isatty() returns True) use the + devices such as NUL (i.e. where ``isatty()`` returns ``True``) use the value of the console input and output codepages at startup, respectively for stdin and stdout/stderr. This defaults to the system locale encoding if the process is not initially attached diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index f7c82729e51d7..fd815ef01716d 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -535,15 +535,15 @@ Reentrant locks also support the :ref:`context management protocol ` There is no return value in this case. When invoked with the *blocking* argument set to true, do the same thing as when - called without arguments, and return true. + called without arguments, and return ``True``. When invoked with the *blocking* argument set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do the - same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do the + same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* - and as long as the lock cannot be acquired. Return true if the lock has + and as long as the lock cannot be acquired. Return ``True`` if the lock has been acquired, false if the timeout has elapsed. .. versionchanged:: 3.2 @@ -776,20 +776,20 @@ Semaphores also support the :ref:`context management protocol `. When invoked without arguments: * If the internal counter is larger than zero on entry, decrement it by - one and return true immediately. + one and return ``True`` immediately. * If the internal counter is zero on entry, block until awoken by a call to :meth:`~Semaphore.release`. Once awoken (and the counter is greater - than 0), decrement the counter by 1 and return true. Exactly one + than 0), decrement the counter by 1 and return ``True``. Exactly one thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. When invoked with *blocking* set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do - the same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do + the same thing as when called without arguments, and return ``True``. When invoked with a *timeout* other than ``None``, it will block for at most *timeout* seconds. If acquire does not complete successfully in - that interval, return false. Return true otherwise. + that interval, return ``False``. Return ``True`` otherwise. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -866,7 +866,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. method:: is_set() - Return true if and only if the internal flag is true. + Return ``True`` if and only if the internal flag is true. .. method:: set() @@ -890,7 +890,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. floating point number specifying a timeout for the operation in seconds (or fractions thereof). - This method returns true if and only if the internal flag has been set to + This method returns ``True`` if and only if the internal flag has been set to true, either before the wait call or after the wait starts, so it will always return ``True`` except if a timeout is given and the operation times out. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 5ba31feae1444..6967d7509657b 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -871,8 +871,8 @@ widget commands. | | remaining values are assumed empty. If there are more values | | | than columns, the extra values are ignored. | +--------+---------------------------------------------------------------+ - | open | True/False value indicating whether the item's children should| - | | be displayed or hidden. | + | open | ``True``/``False`` value indicating whether the item's | + | | children should be displayed or hidden. | +--------+---------------------------------------------------------------+ | tags | A list of tags associated with this item. | +--------+---------------------------------------------------------------+ @@ -997,7 +997,7 @@ ttk.Treeview The minimum width of the column in pixels. The treeview widget will not make the column any smaller than specified by this option when the widget is resized or the user drags a column. - * stretch: True/False + * stretch: ``True``/``False`` Specifies whether the column's width should be adjusted when the widget is resized. * width: width diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 5c641ef46d145..1777929be739d 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -29,17 +29,17 @@ functions. The functions mirror definitions in the Python C header files. .. function:: ISTERMINAL(x) - Return true for terminal token values. + Return ``True`` for terminal token values. .. function:: ISNONTERMINAL(x) - Return true for non-terminal token values. + Return ``True`` for non-terminal token values. .. function:: ISEOF(x) - Return true if *x* is the marker indicating the end of input. + Return ``True`` if *x* is the marker indicating the end of input. The token constants are: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 3fa3cfdaf21a3..746cf765b077f 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -360,7 +360,7 @@ the *new_callable* argument to :func:`patch`. assert the mock has been called with the specified calls. The :attr:`mock_calls` list is checked for the calls. - If *any_order* is false (the default) then the calls must be + If *any_order* is false then the calls must be sequential. There can be extra calls before or after the specified calls. @@ -1006,11 +1006,11 @@ object:: Assert the mock has been awaited with the specified calls. The :attr:`await_args_list` list is checked for the awaits. - If *any_order* is False (the default) then the awaits must be + If *any_order* is false then the awaits must be sequential. There can be extra calls before or after the specified awaits. - If *any_order* is True then the awaits can be in any order, but + If *any_order* is true then the awaits can be in any order, but they must all appear in :attr:`await_args_list`. >>> mock = AsyncMock() @@ -2085,20 +2085,20 @@ to change the default. Methods and their defaults: -* ``__lt__``: NotImplemented -* ``__gt__``: NotImplemented -* ``__le__``: NotImplemented -* ``__ge__``: NotImplemented -* ``__int__``: 1 -* ``__contains__``: False -* ``__len__``: 0 -* ``__iter__``: iter([]) -* ``__exit__``: False -* ``__aexit__``: False -* ``__complex__``: 1j -* ``__float__``: 1.0 -* ``__bool__``: True -* ``__index__``: 1 +* ``__lt__``: ``NotImplemented`` +* ``__gt__``: ``NotImplemented`` +* ``__le__``: ``NotImplemented`` +* ``__ge__``: ``NotImplemented`` +* ``__int__``: ``1`` +* ``__contains__``: ``False`` +* ``__len__``: ``0`` +* ``__iter__``: ``iter([])`` +* ``__exit__``: ``False`` +* ``__aexit__``: ``False`` +* ``__complex__``: ``1j`` +* ``__float__``: ``1.0`` +* ``__bool__``: ``True`` +* ``__index__``: ``1`` * ``__hash__``: default hash for the mock * ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index a834ac75eb1b5..3483ef36a2c33 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -276,9 +276,9 @@ subclass which installs setuptools and pip into a created virtual environment:: This builder installs setuptools and pip so that you can pip or easy_install other packages into the created virtual environment. - :param nodist: If True, setuptools and pip are not installed into the + :param nodist: If true, setuptools and pip are not installed into the created virtual environment. - :param nopip: If True, pip is not installed into the created + :param nopip: If true, pip is not installed into the created virtual environment. :param progress: If setuptools or pip are installed, the progress of the installation can be monitored by passing a progress diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 6edd0714b9df3..1e30aa4a898c1 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -144,7 +144,7 @@ also provides these miscellaneous utilities: .. function:: is_hop_by_hop(header_name) - Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by + Return ``True`` if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by :rfc:`2616`. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 18519a75a5461..98454e18ff1f8 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -210,7 +210,7 @@ DOM Level 2 added the ability to create new :class:`Document` and .. method:: DOMImplementation.hasFeature(feature, version) - Return true if the feature identified by the pair of strings *feature* and + Return ``True`` if the feature identified by the pair of strings *feature* and *version* is implemented. @@ -335,17 +335,17 @@ All of the components of an XML document are subclasses of :class:`Node`. .. method:: Node.hasAttributes() - Returns true if the node has any attributes. + Return ``True`` if the node has any attributes. .. method:: Node.hasChildNodes() - Returns true if the node has any child nodes. + Return ``True`` if the node has any child nodes. .. method:: Node.isSameNode(other) - Returns true if *other* refers to the same node as this node. This is especially + Return ``True`` if *other* refers to the same node as this node. This is especially useful for DOM implementations which use any sort of proxy architecture (because more than one object can refer to the same node). @@ -604,12 +604,12 @@ of that class. .. method:: Element.hasAttribute(name) - Returns true if the element has an attribute named by *name*. + Return ``True`` if the element has an attribute named by *name*. .. method:: Element.hasAttributeNS(namespaceURI, localName) - Returns true if the element has an attribute named by *namespaceURI* and + Return ``True`` if the element has an attribute named by *namespaceURI* and *localName*. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 5e87d8f0285f4..44ac52aa83079 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -574,8 +574,8 @@ Functions .. function:: iselement(element) - Checks if an object appears to be a valid element object. *element* is an - element instance. Returns a true value if this is an element object. + Check if an object appears to be a valid element object. *element* is an + element instance. Return ``True`` if this is an element object. .. function:: iterparse(source, events=None, parser=None) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index e86786a2cc81b..586b5db6fcc06 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -238,9 +238,9 @@ library/urllib.request,,:password,"""joe:password at python.org""" library/urllib.parse,,:scheme, library/urllib.parse,,:scheme,URL:scheme://host/path library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the" +library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If True, pip is not installed into the created" +library/venv,,:param,":param nopip: If true, pip is not installed into the created" library/venv,,:param,:param context: The information for the virtual environment library/xmlrpc.client,,:nil,ex:nil library/xmlrpc.client,,:pass,http://user:pass at host:port/path diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 5c3d5a02b46f1..d975fb7815474 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -926,7 +926,7 @@ logging ------- Added a *force* keyword argument to :func:`logging.basicConfig()` -When set to *True*, any existing handlers attached +When set to true, any existing handlers attached to the root logger are removed and closed before carrying out the configuration specified by the other arguments. @@ -1053,7 +1053,7 @@ environment variable and does not use :envvar:`HOME`, which is not normally set for regular user accounts. (Contributed by Anthony Sottile in :issue:`36264`.) -:func:`~os.path.isdir` on Windows no longer returns true for a link to a +:func:`~os.path.isdir` on Windows no longer returns ``True`` for a link to a non-existent directory. :func:`~os.path.realpath` on Windows now resolves reparse points, including @@ -1102,12 +1102,12 @@ pprint The :mod:`pprint` module added a *sort_dicts* parameter to several functions. By default, those functions continue to sort dictionaries before rendering or -printing. However, if *sort_dicts* is set to *False*, the dictionaries retain +printing. However, if *sort_dicts* is set to false, the dictionaries retain the order that keys were inserted. This can be useful for comparison to JSON inputs during debugging. In addition, there is a convenience new function, :func:`pprint.pp` that is -like :func:`pprint.pprint` but with *sort_dicts* defaulting to *False*:: +like :func:`pprint.pprint` but with *sort_dicts* defaulting to ``False``:: >>> from pprint import pprint, pp >>> d = dict(source='input.txt', operation='filter', destination='output.txt') diff --git a/Lib/difflib.py b/Lib/difflib.py index 3de1b3d0fcdfe..5d756436a67e1 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1074,7 +1074,7 @@ def _qformat(self, aline, bline, atags, btags): def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): r""" - Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + Return True for ignorable line: iff `line` is blank or contains a single '#'. Examples: @@ -1090,7 +1090,7 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): def IS_CHARACTER_JUNK(ch, ws=" \t"): r""" - Return 1 for ignorable character: iff `ch` is a space or tab. + Return True for ignorable character: iff `ch` is a space or tab. Examples: diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 57d5b25728228..9f0e2e5e94e3a 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1051,7 +1051,7 @@ def winfo_class(self): return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): - """Return true if at the last color request the colormap was full.""" + """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) @@ -3224,7 +3224,7 @@ def selection_clear(self, first, last=None): select_clear = selection_clear def selection_includes(self, index): - """Return 1 if INDEX is part of the selection.""" + """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) From webhook-mailer at python.org Tue Nov 12 13:07:32 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 12 Nov 2019 18:07:32 -0000 Subject: [Python-checkins] [3.7] bpo-38738: Fix formatting of True and False. (GH-17083) (GH-17128) Message-ID: https://github.com/python/cpython/commit/42b619ac9aa7f889dcd8eeb14d813f17468454d9 commit: 42b619ac9aa7f889dcd8eeb14d813f17468454d9 branch: 3.7 author: Serhiy Storchaka committer: GitHub date: 2019-11-12T20:07:20+02:00 summary: [3.7] bpo-38738: Fix formatting of True and False. (GH-17083) (GH-17128) * "Return true/false" is replaced with "Return ``True``/``False``" if the function actually returns a bool. * Fixed formatting of some True and False literals (now in monospace). * Replaced "True/False" with "true/false" if it can be not only bool. * Replaced some 1/0 with True/False if it corresponds the code. * "Returns " is replaced with "Return ". (cherry picked from commit 138ccbb02216ca086047c3139857fb44f3dab1f9) files: M Doc/library/asyncio-stream.rst M Doc/library/dataclasses.rst M Doc/library/difflib.rst M Doc/library/doctest.rst M Doc/library/email.compat32-message.rst M Doc/library/email.errors.rst M Doc/library/email.message.rst M Doc/library/fileinput.rst M Doc/library/functions.rst M Doc/library/gc.rst M Doc/library/http.cookiejar.rst M Doc/library/importlib.rst M Doc/library/inspect.rst M Doc/library/ipaddress.rst M Doc/library/keyword.rst M Doc/library/logging.handlers.rst M Doc/library/logging.rst M Doc/library/lzma.rst M Doc/library/msvcrt.rst M Doc/library/optparse.rst M Doc/library/os.rst M Doc/library/parser.rst M Doc/library/sched.rst M Doc/library/ssl.rst M Doc/library/stdtypes.rst M Doc/library/stringprep.rst M Doc/library/sys.rst M Doc/library/threading.rst M Doc/library/tkinter.ttk.rst M Doc/library/token.rst M Doc/library/unittest.mock.rst M Doc/library/venv.rst M Doc/library/wsgiref.rst M Doc/library/xml.dom.rst M Doc/library/xml.etree.elementtree.rst M Doc/tools/susp-ignored.csv M Lib/difflib.py M Lib/tkinter/__init__.py diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 42b4c1f76d3e7..25462653187f9 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -229,8 +229,8 @@ StreamWriter .. method:: can_write_eof() - Return *True* if the underlying transport supports - the :meth:`write_eof` method, *False* otherwise. + Return ``True`` if the underlying transport supports + the :meth:`write_eof` method, ``False`` otherwise. .. method:: write_eof() diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 6af60b6e26949..37258d4ebc738 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -154,7 +154,7 @@ Module-level decorators, classes, and functions method of the superclass will be used (if the superclass is :class:`object`, this means it will fall back to id-based hashing). - - ``frozen``: If true (the default is False), assigning to fields will + - ``frozen``: If true (the default is ``False``), assigning to fields will generate an exception. This emulates read-only frozen instances. If :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then :exc:`TypeError` is raised. See the discussion below. @@ -387,8 +387,8 @@ Module-level decorators, classes, and functions .. function:: is_dataclass(class_or_instance) - Returns True if its parameter is a dataclass or an instance of one, - otherwise returns False. + Return ``True`` if its parameter is a dataclass or an instance of one, + otherwise return ``False``. If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for ``not diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index e245ab81cfb94..1576eb116008b 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -334,14 +334,14 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. function:: IS_LINE_JUNK(line) - Return true for ignorable lines. The line *line* is ignorable if *line* is + Return ``True`` for ignorable lines. The line *line* is ignorable if *line* is blank or contains a single ``'#'``, otherwise it is not ignorable. Used as a default for parameter *linejunk* in :func:`ndiff` in older versions. .. function:: IS_CHARACTER_JUNK(ch) - Return true for ignorable characters. The character *ch* is ignorable if *ch* + Return ``True`` for ignorable characters. The character *ch* is ignorable if *ch* is a space or tab, otherwise it is not ignorable. Used as a default for parameter *charjunk* in :func:`ndiff`. @@ -366,7 +366,7 @@ The :class:`SequenceMatcher` class has this constructor: Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the element is "junk" and should be ignored. Passing ``None`` for *isjunk* is - equivalent to passing ``lambda x: 0``; in other words, no elements are ignored. + equivalent to passing ``lambda x: False``; in other words, no elements are ignored. For example, pass:: lambda x: x in " \t" diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index e7c0033eb6bc4..3e5e1014ab453 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1531,7 +1531,7 @@ OutputChecker objects A class used to check the whether the actual output from a doctest example matches the expected output. :class:`OutputChecker` defines two methods: - :meth:`check_output`, which compares a given pair of outputs, and returns true + :meth:`check_output`, which compares a given pair of outputs, and returns ``True`` if they match; and :meth:`output_difference`, which returns a string describing the differences between two outputs. diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 09ea64a5a01aa..745b3a6a3ad42 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -308,7 +308,7 @@ Here are the methods of the :class:`Message` class: .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done case-insensitively and *name* should not include the trailing colon. Used for the ``in`` operator, e.g.:: diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 511ad16358319..f4b9f52509689 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -99,7 +99,7 @@ All defect classes are subclassed from :class:`email.errors.MessageDefect`. * :class:`MultipartInvariantViolationDefect` -- A message claimed to be a :mimetype:`multipart`, but no subparts were found. Note that when a message has this defect, its :meth:`~email.message.Message.is_multipart` method may - return false even though its content type claims to be :mimetype:`multipart`. + return ``False`` even though its content type claims to be :mimetype:`multipart`. * :class:`InvalidBase64PaddingDefect` -- When decoding a block of base64 encoded bytes, the padding was not correct. Enough padding is added to diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 77b8099a7d4cd..6c07e579db852 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -178,7 +178,7 @@ message objects. .. method:: __contains__(name) - Return true if the message object has a field named *name*. Matching is + Return ``True`` if the message object has a field named *name*. Matching is done without regard to case and *name* does not include the trailing colon. Used for the ``in`` operator. For example:: diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index bf81749f94562..a21c76d93567c 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -108,14 +108,14 @@ if there is no active state, :exc:`RuntimeError` is raised. .. function:: isfirstline() - Returns true if the line just read is the first line of its file, otherwise - returns false. + Return ``True`` if the line just read is the first line of its file, otherwise + return ``False``. .. function:: isstdin() - Returns true if the last line was read from ``sys.stdin``, otherwise returns - false. + Return ``True`` if the last line was read from ``sys.stdin``, otherwise return + ``False``. .. function:: nextfile() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ff51a4a32cc57..72d82ae87e6f9 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -178,8 +178,8 @@ are always available. They are listed here in alphabetical order. .. function:: callable(object) Return :const:`True` if the *object* argument appears callable, - :const:`False` if not. If this returns true, it is still possible that a - call fails, but if it is false, calling *object* will never succeed. + :const:`False` if not. If this returns ``True``, it is still possible that a + call fails, but if it is ``False``, calling *object* will never succeed. Note that classes are callable (calling a class returns a new instance); instances are callable if their class has a :meth:`__call__` method. @@ -777,19 +777,19 @@ are always available. They are listed here in alphabetical order. .. function:: isinstance(object, classinfo) - Return true if the *object* argument is an instance of the *classinfo* + Return ``True`` if the *object* argument is an instance of the *classinfo* argument, or of a (direct, indirect or :term:`virtual `) subclass thereof. If *object* is not - an object of the given type, the function always returns false. + an object of the given type, the function always returns ``False``. If *classinfo* is a tuple of type objects (or recursively, other such - tuples), return true if *object* is an instance of any of the types. + tuples), return ``True`` if *object* is an instance of any of the types. If *classinfo* is not a type or tuple of types and such tuples, a :exc:`TypeError` exception is raised. .. function:: issubclass(class, classinfo) - Return true if *class* is a subclass (direct, indirect or :term:`virtual + Return ``True`` if *class* is a subclass (direct, indirect or :term:`virtual `) of *classinfo*. A class is considered a subclass of itself. *classinfo* may be a tuple of class objects, in which case every entry in *classinfo* will be checked. In any other diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index d428c33e87679..af45581e33527 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -35,7 +35,7 @@ The :mod:`gc` module provides the following functions: .. function:: isenabled() - Returns true if automatic collection is enabled. + Return ``True`` if automatic collection is enabled. .. function:: collect(generation=2) diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index 8bacd72c811a8..54aca1576df86 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -369,7 +369,7 @@ methods: .. method:: CookiePolicy.domain_return_ok(domain, request) - Return false if cookies should not be returned, given cookie domain. + Return ``False`` if cookies should not be returned, given cookie domain. This method is an optimization. It removes the need for checking every cookie with a particular domain (which might involve reading many files). Returning @@ -393,7 +393,7 @@ methods: .. method:: CookiePolicy.path_return_ok(path, request) - Return false if cookies should not be returned, given cookie path. + Return ``False`` if cookies should not be returned, given cookie path. See the documentation for :meth:`domain_return_ok`. @@ -702,7 +702,7 @@ accessed using the following methods: .. method:: Cookie.has_nonstandard_attr(name) - Return true if cookie has the named cookie-attribute. + Return ``True`` if cookie has the named cookie-attribute. .. method:: Cookie.get_nonstandard_attr(name, default=None) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 974dbb461a158..0057eab3649bf 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1168,7 +1168,7 @@ find and load modules. .. method:: is_package(fullname) - Return true if :attr:`path` appears to be for a package. + Return ``True`` if :attr:`path` appears to be for a package. .. method:: path_stats(path) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 18cbacf3e8db5..d52726d07a985 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -273,39 +273,39 @@ attributes: .. function:: ismodule(object) - Return true if the object is a module. + Return ``True`` if the object is a module. .. function:: isclass(object) - Return true if the object is a class, whether built-in or created in Python + Return ``True`` if the object is a class, whether built-in or created in Python code. .. function:: ismethod(object) - Return true if the object is a bound method written in Python. + Return ``True`` if the object is a bound method written in Python. .. function:: isfunction(object) - Return true if the object is a Python function, which includes functions + Return ``True`` if the object is a Python function, which includes functions created by a :term:`lambda` expression. .. function:: isgeneratorfunction(object) - Return true if the object is a Python generator function. + Return ``True`` if the object is a Python generator function. .. function:: isgenerator(object) - Return true if the object is a generator. + Return ``True`` if the object is a generator. .. function:: iscoroutinefunction(object) - Return true if the object is a :term:`coroutine function` + Return ``True`` if the object is a :term:`coroutine function` (a function defined with an :keyword:`async def` syntax). .. versionadded:: 3.5 @@ -313,7 +313,7 @@ attributes: .. function:: iscoroutine(object) - Return true if the object is a :term:`coroutine` created by an + Return ``True`` if the object is a :term:`coroutine` created by an :keyword:`async def` function. .. versionadded:: 3.5 @@ -321,7 +321,7 @@ attributes: .. function:: isawaitable(object) - Return true if the object can be used in :keyword:`await` expression. + Return ``True`` if the object can be used in :keyword:`await` expression. Can also be used to distinguish generator-based coroutines from regular generators:: @@ -340,7 +340,7 @@ attributes: .. function:: isasyncgenfunction(object) - Return true if the object is an :term:`asynchronous generator` function, + Return ``True`` if the object is an :term:`asynchronous generator` function, for example:: >>> async def agen(): @@ -354,44 +354,44 @@ attributes: .. function:: isasyncgen(object) - Return true if the object is an :term:`asynchronous generator iterator` + Return ``True`` if the object is an :term:`asynchronous generator iterator` created by an :term:`asynchronous generator` function. .. versionadded:: 3.6 .. function:: istraceback(object) - Return true if the object is a traceback. + Return ``True`` if the object is a traceback. .. function:: isframe(object) - Return true if the object is a frame. + Return ``True`` if the object is a frame. .. function:: iscode(object) - Return true if the object is a code. + Return ``True`` if the object is a code. .. function:: isbuiltin(object) - Return true if the object is a built-in function or a bound built-in method. + Return ``True`` if the object is a built-in function or a bound built-in method. .. function:: isroutine(object) - Return true if the object is a user-defined or built-in function or method. + Return ``True`` if the object is a user-defined or built-in function or method. .. function:: isabstract(object) - Return true if the object is an abstract base class. + Return ``True`` if the object is an abstract base class. .. function:: ismethoddescriptor(object) - Return true if the object is a method descriptor, but not if + Return ``True`` if the object is a method descriptor, but not if :func:`ismethod`, :func:`isclass`, :func:`isfunction` or :func:`isbuiltin` are true. @@ -402,14 +402,14 @@ attributes: sensible, and :attr:`__doc__` often is. Methods implemented via descriptors that also pass one of the other tests - return false from the :func:`ismethoddescriptor` test, simply because the + return ``False`` from the :func:`ismethoddescriptor` test, simply because the other tests promise more -- you can, e.g., count on having the :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`. .. function:: isdatadescriptor(object) - Return true if the object is a data descriptor. + Return ``True`` if the object is a data descriptor. Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. Examples are properties (defined in Python), getsets, and members. The @@ -422,7 +422,7 @@ attributes: .. function:: isgetsetdescriptor(object) - Return true if the object is a getset descriptor. + Return ``True`` if the object is a getset descriptor. .. impl-detail:: @@ -433,7 +433,7 @@ attributes: .. function:: ismemberdescriptor(object) - Return true if the object is a member descriptor. + Return ``True`` if the object is a member descriptor. .. impl-detail:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index b7b502aff15e0..140401d2f3673 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -557,7 +557,7 @@ dictionaries. .. method:: subnet_of(other) - Returns *True* if this network is a subnet of *other*. + Return ``True`` if this network is a subnet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') @@ -568,7 +568,7 @@ dictionaries. .. method:: supernet_of(other) - Returns *True* if this network is a supernet of *other*. + Return ``True`` if this network is a supernet of *other*. >>> a = ip_network('192.168.1.0/24') >>> b = ip_network('192.168.1.128/30') diff --git a/Doc/library/keyword.rst b/Doc/library/keyword.rst index 173db23544a47..3768df969c55c 100644 --- a/Doc/library/keyword.rst +++ b/Doc/library/keyword.rst @@ -13,7 +13,7 @@ This module allows a Python program to determine if a string is a keyword. .. function:: iskeyword(s) - Return true if *s* is a Python keyword. + Return ``True`` if *s* is a Python keyword. .. data:: kwlist diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 0e9870408ff43..fa0424dcd18f5 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -846,8 +846,8 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: emit(record) - Appends the record to the buffer. If :meth:`shouldFlush` returns true, - calls :meth:`flush` to process the buffer. + Append the record to the buffer. If :meth:`shouldFlush` returns true, + call :meth:`flush` to process the buffer. .. method:: flush() @@ -858,7 +858,7 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: shouldFlush(record) - Returns true if the buffer is up to capacity. This method can be + Return ``True`` if the buffer is up to capacity. This method can be overridden to implement custom flushing strategies. diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index cec2f142dfc11..f1ab49fd140a0 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -283,7 +283,7 @@ is the module's name in the Python package namespace. .. method:: Logger.filter(record) - Applies this logger's filters to the record and returns a true value if the + Apply this logger's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be processed (passed to handlers). If one returns a false value, no @@ -429,7 +429,7 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call .. method:: Handler.filter(record) - Applies this handler's filters to the record and returns a true value if the + Apply this handler's filters to the record and return ``True`` if the record is to be processed. The filters are consulted in turn, until one of them returns a false value. If none of them return a false value, the record will be emitted. If one returns a false value, the handler will not emit the diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index cce6c23e611e3..4bfff9c6147ed 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -313,7 +313,7 @@ Miscellaneous .. function:: is_check_supported(check) - Returns true if the given integrity check is supported on this system. + Return ``True`` if the given integrity check is supported on this system. :const:`CHECK_NONE` and :const:`CHECK_CRC32` are always supported. :const:`CHECK_CRC64` and :const:`CHECK_SHA256` may be unavailable if you are diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index bd34ffb1b2335..14ad2cd4373af 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -92,7 +92,7 @@ Console I/O .. function:: kbhit() - Return true if a keypress is waiting to be read. + Return ``True`` if a keypress is waiting to be read. .. function:: getch() diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 3afc77bf9f8ec..36110bbfa79ce 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -928,10 +928,10 @@ The canonical way to create an :class:`Option` instance is with the store a constant value ``"store_true"`` - store a true value + store ``True`` ``"store_false"`` - store a false value + store ``False`` ``"append"`` append this option's argument to a list @@ -1135,12 +1135,12 @@ must specify for any option using that action. * ``"store_true"`` [relevant: :attr:`~Option.dest`] - A special case of ``"store_const"`` that stores a true value to + A special case of ``"store_const"`` that stores ``True`` to :attr:`~Option.dest`. * ``"store_false"`` [relevant: :attr:`~Option.dest`] - Like ``"store_true"``, but stores a false value. + Like ``"store_true"``, but stores ``False``. Example:: @@ -1396,7 +1396,7 @@ provides several methods to help you out: .. method:: OptionParser.has_option(opt_str) - Return true if the OptionParser has an option with option string *opt_str* + Return ``True`` if the OptionParser has an option with option string *opt_str* (e.g., ``-q`` or ``--verbose``). .. method:: OptionParser.remove_option(opt_str) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 1556422a17043..10d7deaecdcae 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -147,7 +147,7 @@ process and user. versa). :data:`environb` is only available if :data:`supports_bytes_environ` is - True. + ``True``. .. versionadded:: 3.2 @@ -235,7 +235,7 @@ process and user. *default* if it doesn't. *key*, *default* and the result are bytes. :func:`getenvb` is only available if :data:`supports_bytes_environ` - is True. + is ``True``. .. availability:: most flavors of Unix. diff --git a/Doc/library/parser.rst b/Doc/library/parser.rst index 1d2da300709c8..7b380c367028c 100644 --- a/Doc/library/parser.rst +++ b/Doc/library/parser.rst @@ -234,8 +234,8 @@ determine if an ST was created from source code via :func:`expr` or .. index:: builtin: compile - When *st* represents an ``'eval'`` form, this function returns true, otherwise - it returns false. This is useful, since code objects normally cannot be queried + When *st* represents an ``'eval'`` form, this function returns ``True``, otherwise + it returns ``False``. This is useful, since code objects normally cannot be queried for this information using existing built-in functions. Note that the code objects created by :func:`compilest` cannot be queried like this either, and are identical to those created by the built-in :func:`compile` function. diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 03753af4b2d50..047899e7666f8 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -104,7 +104,7 @@ Scheduler Objects .. method:: scheduler.empty() - Return true if the event queue is empty. + Return ``True`` if the event queue is empty. .. method:: scheduler.run(blocking=True) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 3730d74e05d63..212d937b7ebb1 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1649,7 +1649,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is - False. + ``False``. OpenSSL 1.1.0 to 1.1.0e will abort the handshake and raise :exc:`SSLError` when both sides support ALPN but cannot agree on a protocol. 1.1.0f+ @@ -1668,7 +1668,7 @@ to speed up repeated connections from the same clients. return the agreed-upon protocol. This method will raise :exc:`NotImplementedError` if :data:`HAS_NPN` is - False. + ``False``. .. versionadded:: 3.3 diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 57b72c5b65620..5e9b59eb84bbb 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1648,16 +1648,16 @@ expression support in the :mod:`re` module). .. method:: str.isalnum() - Return true if all characters in the string are alphanumeric and there is at - least one character, false otherwise. A character ``c`` is alphanumeric if one + Return ``True`` if all characters in the string are alphanumeric and there is at + least one character, ``False`` otherwise. A character ``c`` is alphanumeric if one of the following returns ``True``: ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or ``c.isnumeric()``. .. method:: str.isalpha() - Return true if all characters in the string are alphabetic and there is at least - one character, false otherwise. Alphabetic characters are those characters defined + Return ``True`` if all characters in the string are alphabetic and there is at least + one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different from the "Alphabetic" property defined in the Unicode Standard. @@ -1665,8 +1665,8 @@ expression support in the :mod:`re` module). .. method:: str.isascii() - Return true if the string is empty or all characters in the string are ASCII, - false otherwise. + Return ``True`` if the string is empty or all characters in the string are ASCII, + ``False`` otherwise. ASCII characters have code points in the range U+0000-U+007F. .. versionadded:: 3.7 @@ -1674,8 +1674,8 @@ expression support in the :mod:`re` module). .. method:: str.isdecimal() - Return true if all characters in the string are decimal - characters and there is at least one character, false + Return ``True`` if all characters in the string are decimal + characters and there is at least one character, ``False`` otherwise. Decimal characters are those that can be used to form numbers in base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in the Unicode @@ -1684,8 +1684,8 @@ expression support in the :mod:`re` module). .. method:: str.isdigit() - Return true if all characters in the string are digits and there is at least one - character, false otherwise. Digits include decimal characters and digits that need + Return ``True`` if all characters in the string are digits and there is at least one + character, ``False`` otherwise. Digits include decimal characters and digits that need special handling, such as the compatibility superscript digits. This covers digits which cannot be used to form numbers in base 10, like the Kharosthi numbers. Formally, a digit is a character that has the @@ -1694,7 +1694,7 @@ expression support in the :mod:`re` module). .. method:: str.isidentifier() - Return true if the string is a valid identifier according to the language + Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. Use :func:`keyword.iskeyword` to test for reserved identifiers such as @@ -1702,14 +1702,14 @@ expression support in the :mod:`re` module). .. method:: str.islower() - Return true if all cased characters [4]_ in the string are lowercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are lowercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.isnumeric() - Return true if all characters in the string are numeric - characters, and there is at least one character, false + Return ``True`` if all characters in the string are numeric + characters, and there is at least one character, ``False`` otherwise. Numeric characters include digit characters, and all characters that have the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric characters are those with the property @@ -1718,8 +1718,8 @@ expression support in the :mod:`re` module). .. method:: str.isprintable() - Return true if all characters in the string are printable or the string is - empty, false otherwise. Nonprintable characters are those characters defined + Return ``True`` if all characters in the string are printable or the string is + empty, ``False`` otherwise. Nonprintable characters are those characters defined in the Unicode character database as "Other" or "Separator", excepting the ASCII space (0x20) which is considered printable. (Note that printable characters in this context are those which should not be escaped when @@ -1729,8 +1729,8 @@ expression support in the :mod:`re` module). .. method:: str.isspace() - Return true if there are only whitespace characters in the string and there is - at least one character, false otherwise. + Return ``True`` if there are only whitespace characters in the string and there is + at least one character, ``False`` otherwise. A character is *whitespace* if in the Unicode character database (see :mod:`unicodedata`), either its general category is ``Zs`` @@ -1740,15 +1740,15 @@ expression support in the :mod:`re` module). .. method:: str.istitle() - Return true if the string is a titlecased string and there is at least one + Return ``True`` if the string is a titlecased string and there is at least one character, for example uppercase characters may only follow uncased characters - and lowercase characters only cased ones. Return false otherwise. + and lowercase characters only cased ones. Return ``False`` otherwise. .. method:: str.isupper() - Return true if all cased characters [4]_ in the string are uppercase and - there is at least one cased character, false otherwise. + Return ``True`` if all cased characters [4]_ in the string are uppercase and + there is at least one cased character, ``False`` otherwise. .. method:: str.join(iterable) @@ -2944,8 +2944,8 @@ place, and instead produce new objects. .. method:: bytes.isalnum() bytearray.isalnum() - Return true if all bytes in the sequence are alphabetical ASCII characters - or ASCII decimal digits and the sequence is not empty, false otherwise. + Return ``True`` if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. @@ -2961,8 +2961,8 @@ place, and instead produce new objects. .. method:: bytes.isalpha() bytearray.isalpha() - Return true if all bytes in the sequence are alphabetic ASCII characters - and the sequence is not empty, false otherwise. Alphabetic ASCII + Return ``True`` if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, ``False`` otherwise. Alphabetic ASCII characters are those byte values in the sequence ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. @@ -2977,8 +2977,8 @@ place, and instead produce new objects. .. method:: bytes.isascii() bytearray.isascii() - Return true if the sequence is empty or all bytes in the sequence are ASCII, - false otherwise. + Return ``True`` if the sequence is empty or all bytes in the sequence are ASCII, + ``False`` otherwise. ASCII bytes are in the range 0-0x7F. .. versionadded:: 3.7 @@ -2987,8 +2987,8 @@ place, and instead produce new objects. .. method:: bytes.isdigit() bytearray.isdigit() - Return true if all bytes in the sequence are ASCII decimal digits - and the sequence is not empty, false otherwise. ASCII decimal digits are + Return ``True`` if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, ``False`` otherwise. ASCII decimal digits are those byte values in the sequence ``b'0123456789'``. For example:: @@ -3002,8 +3002,8 @@ place, and instead produce new objects. .. method:: bytes.islower() bytearray.islower() - Return true if there is at least one lowercase ASCII character - in the sequence and no uppercase ASCII characters, false otherwise. + Return ``True`` if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, ``False`` otherwise. For example:: @@ -3020,8 +3020,8 @@ place, and instead produce new objects. .. method:: bytes.isspace() bytearray.isspace() - Return true if all bytes in the sequence are ASCII whitespace and the - sequence is not empty, false otherwise. ASCII whitespace characters are + Return ``True`` if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, ``False`` otherwise. ASCII whitespace characters are those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). @@ -3029,8 +3029,8 @@ place, and instead produce new objects. .. method:: bytes.istitle() bytearray.istitle() - Return true if the sequence is ASCII titlecase and the sequence is not - empty, false otherwise. See :meth:`bytes.title` for more details on the + Return ``True`` if the sequence is ASCII titlecase and the sequence is not + empty, ``False`` otherwise. See :meth:`bytes.title` for more details on the definition of "titlecase". For example:: @@ -3044,8 +3044,8 @@ place, and instead produce new objects. .. method:: bytes.isupper() bytearray.isupper() - Return true if there is at least one uppercase alphabetic ASCII character - in the sequence and no lowercase ASCII characters, false otherwise. + Return ``True`` if there is at least one uppercase alphabetic ASCII character + in the sequence and no lowercase ASCII characters, ``False`` otherwise. For example:: diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 330032ba1c0ba..5cfb533d802db 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -34,7 +34,7 @@ itself was generated using the ``mkstringprep.py`` utility. As a result, these tables are exposed as functions, not as data structures. There are two kinds of tables in the RFC: sets and mappings. For a set, :mod:`stringprep` provides the "characteristic function", i.e. a function that -returns true if the parameter is part of the set. For mappings, it provides the +returns ``True`` if the parameter is part of the set. For mappings, it provides the mapping function: given the key, it returns the associated value. Below is a list of all functions available in the module. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 822e22e334bbe..45708686c1773 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1377,7 +1377,7 @@ always available. On Windows, UTF-8 is used for the console device. Non-character devices such as disk files and pipes use the system locale encoding (i.e. the ANSI codepage). Non-console character - devices such as NUL (i.e. where isatty() returns True) use the + devices such as NUL (i.e. where ``isatty()`` returns ``True``) use the value of the console input and output codepages at startup, respectively for stdin and stdout/stderr. This defaults to the system locale encoding if the process is not initially attached diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index c58a6ad75d08f..6fcdd42d6080d 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -465,15 +465,15 @@ Reentrant locks also support the :ref:`context management protocol ` There is no return value in this case. When invoked with the *blocking* argument set to true, do the same thing as when - called without arguments, and return true. + called without arguments, and return ``True``. When invoked with the *blocking* argument set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do the - same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do the + same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* - and as long as the lock cannot be acquired. Return true if the lock has + and as long as the lock cannot be acquired. Return ``True`` if the lock has been acquired, false if the timeout has elapsed. .. versionchanged:: 3.2 @@ -706,20 +706,20 @@ Semaphores also support the :ref:`context management protocol `. When invoked without arguments: * If the internal counter is larger than zero on entry, decrement it by - one and return true immediately. + one and return ``True`` immediately. * If the internal counter is zero on entry, block until awoken by a call to :meth:`~Semaphore.release`. Once awoken (and the counter is greater - than 0), decrement the counter by 1 and return true. Exactly one + than 0), decrement the counter by 1 and return ``True``. Exactly one thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. When invoked with *blocking* set to false, do not block. If a call - without an argument would block, return false immediately; otherwise, do - the same thing as when called without arguments, and return true. + without an argument would block, return ``False`` immediately; otherwise, do + the same thing as when called without arguments, and return ``True``. When invoked with a *timeout* other than ``None``, it will block for at most *timeout* seconds. If acquire does not complete successfully in - that interval, return false. Return true otherwise. + that interval, return ``False``. Return ``True`` otherwise. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -796,7 +796,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. .. method:: is_set() - Return true if and only if the internal flag is true. + Return ``True`` if and only if the internal flag is true. .. method:: set() @@ -820,7 +820,7 @@ method. The :meth:`~Event.wait` method blocks until the flag is true. floating point number specifying a timeout for the operation in seconds (or fractions thereof). - This method returns true if and only if the internal flag has been set to + This method returns ``True`` if and only if the internal flag has been set to true, either before the wait call or after the wait starts, so it will always return ``True`` except if a timeout is given and the operation times out. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 76ecfcce49777..f9084c5cac3c5 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -871,8 +871,8 @@ widget commands. | | remaining values are assumed empty. If there are more values | | | than columns, the extra values are ignored. | +--------+---------------------------------------------------------------+ - | open | True/False value indicating whether the item's children should| - | | be displayed or hidden. | + | open | ``True``/``False`` value indicating whether the item's | + | | children should be displayed or hidden. | +--------+---------------------------------------------------------------+ | tags | A list of tags associated with this item. | +--------+---------------------------------------------------------------+ @@ -997,7 +997,7 @@ ttk.Treeview The minimum width of the column in pixels. The treeview widget will not make the column any smaller than specified by this option when the widget is resized or the user drags a column. - * stretch: True/False + * stretch: ``True``/``False`` Specifies whether the column's width should be adjusted when the widget is resized. * width: width diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 373991027e4ca..c56cb766518f4 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -29,17 +29,17 @@ functions. The functions mirror definitions in the Python C header files. .. function:: ISTERMINAL(x) - Return true for terminal token values. + Return ``True`` for terminal token values. .. function:: ISNONTERMINAL(x) - Return true for non-terminal token values. + Return ``True`` for non-terminal token values. .. function:: ISEOF(x) - Return true if *x* is the marker indicating the end of input. + Return ``True`` if *x* is the marker indicating the end of input. The token constants are: diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 36cc0c2fc4bdc..2e192bef58903 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -336,7 +336,7 @@ the *new_callable* argument to :func:`patch`. assert the mock has been called with the specified calls. The :attr:`mock_calls` list is checked for the calls. - If *any_order* is false (the default) then the calls must be + If *any_order* is false then the calls must be sequential. There can be extra calls before or after the specified calls. @@ -1765,19 +1765,19 @@ to change the default. Methods and their defaults: -* ``__lt__``: NotImplemented -* ``__gt__``: NotImplemented -* ``__le__``: NotImplemented -* ``__ge__``: NotImplemented -* ``__int__``: 1 -* ``__contains__``: False -* ``__len__``: 0 -* ``__iter__``: iter([]) -* ``__exit__``: False -* ``__complex__``: 1j -* ``__float__``: 1.0 -* ``__bool__``: True -* ``__index__``: 1 +* ``__lt__``: ``NotImplemented`` +* ``__gt__``: ``NotImplemented`` +* ``__le__``: ``NotImplemented`` +* ``__ge__``: ``NotImplemented`` +* ``__int__``: ``1`` +* ``__contains__``: ``False`` +* ``__len__``: ``0`` +* ``__iter__``: ``iter([])`` +* ``__exit__``: ``False`` +* ``__complex__``: ``1j`` +* ``__float__``: ``1.0`` +* ``__bool__``: ``True`` +* ``__index__``: ``1`` * ``__hash__``: default hash for the mock * ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 18804b5eed64a..47324f0520dfd 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -273,9 +273,9 @@ subclass which installs setuptools and pip into a created virtual environment:: This builder installs setuptools and pip so that you can pip or easy_install other packages into the created virtual environment. - :param nodist: If True, setuptools and pip are not installed into the + :param nodist: If true, setuptools and pip are not installed into the created virtual environment. - :param nopip: If True, pip is not installed into the created + :param nopip: If true, pip is not installed into the created virtual environment. :param progress: If setuptools or pip are installed, the progress of the installation can be monitored by passing a progress diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 2d9b7b359e806..95fd188f0eda8 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -144,7 +144,7 @@ also provides these miscellaneous utilities: .. function:: is_hop_by_hop(header_name) - Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by + Return ``True`` if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header, as defined by :rfc:`2616`. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 18519a75a5461..98454e18ff1f8 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -210,7 +210,7 @@ DOM Level 2 added the ability to create new :class:`Document` and .. method:: DOMImplementation.hasFeature(feature, version) - Return true if the feature identified by the pair of strings *feature* and + Return ``True`` if the feature identified by the pair of strings *feature* and *version* is implemented. @@ -335,17 +335,17 @@ All of the components of an XML document are subclasses of :class:`Node`. .. method:: Node.hasAttributes() - Returns true if the node has any attributes. + Return ``True`` if the node has any attributes. .. method:: Node.hasChildNodes() - Returns true if the node has any child nodes. + Return ``True`` if the node has any child nodes. .. method:: Node.isSameNode(other) - Returns true if *other* refers to the same node as this node. This is especially + Return ``True`` if *other* refers to the same node as this node. This is especially useful for DOM implementations which use any sort of proxy architecture (because more than one object can refer to the same node). @@ -604,12 +604,12 @@ of that class. .. method:: Element.hasAttribute(name) - Returns true if the element has an attribute named by *name*. + Return ``True`` if the element has an attribute named by *name*. .. method:: Element.hasAttributeNS(namespaceURI, localName) - Returns true if the element has an attribute named by *namespaceURI* and + Return ``True`` if the element has an attribute named by *namespaceURI* and *localName*. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index ca6bdf6095b8a..ec38f09f76de0 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -510,8 +510,8 @@ Functions .. function:: iselement(element) - Checks if an object appears to be a valid element object. *element* is an - element instance. Returns a true value if this is an element object. + Check if an object appears to be a valid element object. *element* is an + element instance. Return ``True`` if this is an element object. .. function:: iterparse(source, events=None, parser=None) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 0eb9901d3ccf5..0c738f0204a2d 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -239,9 +239,9 @@ library/urllib.request,,:port,:port library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n\n" library/urllib.request,,:password,"""joe:password at python.org""" library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the" +library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If True, pip is not installed into the created" +library/venv,,:param,":param nopip: If true, pip is not installed into the created" library/venv,,:param,:param context: The information for the virtual environment library/xmlrpc.client,,:nil,ex:nil library/xmlrpc.client,,:pass,http://user:pass at host:port/path diff --git a/Lib/difflib.py b/Lib/difflib.py index 887c3c26cae45..9528690e788bc 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1085,7 +1085,7 @@ def _qformat(self, aline, bline, atags, btags): def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): r""" - Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + Return True for ignorable line: iff `line` is blank or contains a single '#'. Examples: @@ -1101,7 +1101,7 @@ def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match): def IS_CHARACTER_JUNK(ch, ws=" \t"): r""" - Return 1 for ignorable character: iff `ch` is a space or tab. + Return True for ignorable character: iff `ch` is a space or tab. Examples: diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index a6e8fb2e611bb..92f64ac2253d1 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -969,7 +969,7 @@ def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): - """Return true if at the last color request the colormap was full.""" + """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): @@ -2829,7 +2829,7 @@ def selection_clear(self, first, last=None): 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): - """Return 1 if INDEX is part of the selection.""" + """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes From webhook-mailer at python.org Tue Nov 12 17:42:57 2019 From: webhook-mailer at python.org (Steve Dower) Date: Tue, 12 Nov 2019 22:42:57 -0000 Subject: [Python-checkins] bpo-38723: Pdb._runscript should use io.open_code() instead of open() (GH-17127) Message-ID: https://github.com/python/cpython/commit/d593881505c1f4acfd17f41312b27cc898451816 commit: d593881505c1f4acfd17f41312b27cc898451816 branch: master author: jsnklln committer: Steve Dower date: 2019-11-12T14:42:47-08:00 summary: bpo-38723: Pdb._runscript should use io.open_code() instead of open() (GH-17127) Co-Authored-By: Brandt Bucher files: A Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst M Lib/pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 8639204891cb0..bf503f1e73ee1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -68,6 +68,7 @@ # commands and is appended to __doc__ after the class has been defined. import os +import io import re import sys import cmd @@ -1565,7 +1566,7 @@ def _runscript(self, filename): self._wait_for_mainpyfile = True self.mainpyfile = self.canonic(filename) self._user_requested_quit = False - with open(filename, "rb") as fp: + with io.open_code(filename) as fp: statement = "exec(compile(%r, %r, 'exec'))" % \ (fp.read(), self.mainpyfile) self.run(statement) diff --git a/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst b/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst new file mode 100644 index 0000000000000..c84bb8589d303 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst @@ -0,0 +1 @@ +:mod:`pdb` now uses :meth:`io.open_code` to trigger auditing events. From webhook-mailer at python.org Tue Nov 12 17:51:46 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 12 Nov 2019 22:51:46 -0000 Subject: [Python-checkins] closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17112) Message-ID: https://github.com/python/cpython/commit/74fa9f723f700a342e582b5ad4b51a2c4801cd1c commit: 74fa9f723f700a342e582b5ad4b51a2c4801cd1c branch: master author: Benjamin Peterson committer: GitHub date: 2019-11-12T14:51:34-08:00 summary: closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17112) This change, which follows the behavior of C stdio's fdopen and Python 2's file object, allows pipes to be opened in append mode. files: A Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst M Lib/_pyio.py M Lib/test/test_io.py M Modules/_io/fileio.c diff --git a/Lib/_pyio.py b/Lib/_pyio.py index e819b0a3cce85..4c2414672ed56 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1577,7 +1577,11 @@ def __init__(self, file, mode='r', closefd=True, opener=None): # For consistent behaviour, we explicitly seek to the # end of file (otherwise, it might be done only on the # first write()). - os.lseek(fd, 0, SEEK_END) + try: + os.lseek(fd, 0, SEEK_END) + except OSError as e: + if e.errno != errno.ESPIPE: + raise except: if owned_fd is not None: os.close(owned_fd) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index ad22dfe9b2910..501e9313963bb 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3906,6 +3906,17 @@ def test_removed_u_mode(self): self.open(support.TESTFN, mode) self.assertIn('invalid mode', str(cm.exception)) + def test_open_pipe_with_append(self): + # bpo-27805: Ignore ESPIPE from lseek() in open(). + r, w = os.pipe() + self.addCleanup(os.close, r) + f = self.open(w, 'a') + self.addCleanup(f.close) + # Check that the file is marked non-seekable. On Windows, however, lseek + # somehow succeeds on pipes. + if sys.platform != 'win32': + self.assertFalse(f.seekable()) + def test_io_after_close(self): for kwargs in [ {"mode": "w"}, diff --git a/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst new file mode 100644 index 0000000000000..37be6a5d0b22b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst @@ -0,0 +1,2 @@ +Allow opening pipes and other non-seekable files in append mode with +:func:`open`. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index fd32b19212605..1855b83449d2a 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_object.h" #include "structmember.h" +#include #ifdef HAVE_SYS_TYPES_H #include #endif @@ -75,7 +76,7 @@ _Py_IDENTIFIER(name); #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ -static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence); +static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); int _PyFileIO_closed(PyObject *self) @@ -480,7 +481,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ - PyObject *pos = portable_lseek(self, NULL, 2); + PyObject *pos = portable_lseek(self, NULL, 2, true); if (pos == NULL) goto error; Py_DECREF(pos); @@ -603,7 +604,7 @@ _io_FileIO_seekable_impl(fileio *self) return err_closed(); if (self->seekable < 0) { /* portable_lseek() sets the seekable attribute */ - PyObject *pos = portable_lseek(self, NULL, SEEK_CUR); + PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); assert(self->seekable >= 0); if (pos == NULL) { PyErr_Clear(); @@ -870,7 +871,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b) /* Cribbed from posix_lseek() */ static PyObject * -portable_lseek(fileio *self, PyObject *posobj, int whence) +portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) { Py_off_t pos, res; int fd = self->fd; @@ -921,8 +922,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence) self->seekable = (res >= 0); } - if (res < 0) - return PyErr_SetFromErrno(PyExc_OSError); + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + return PyErr_SetFromErrno(PyExc_OSError); + } + } #if defined(HAVE_LARGEFILE_SUPPORT) return PyLong_FromLongLong(res); @@ -955,7 +961,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) if (self->fd < 0) return err_closed(); - return portable_lseek(self, pos, whence); + return portable_lseek(self, pos, whence, false); } /*[clinic input] @@ -973,7 +979,7 @@ _io_FileIO_tell_impl(fileio *self) if (self->fd < 0) return err_closed(); - return portable_lseek(self, NULL, 1); + return portable_lseek(self, NULL, 1, false); } #ifdef HAVE_FTRUNCATE @@ -1004,7 +1010,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (posobj == Py_None) { /* Get the current position. */ - posobj = portable_lseek(self, NULL, 1); + posobj = portable_lseek(self, NULL, 1, false); if (posobj == NULL) return NULL; } From webhook-mailer at python.org Tue Nov 12 18:09:12 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 12 Nov 2019 23:09:12 -0000 Subject: [Python-checkins] bpo-38723: Pdb._runscript should use io.open_code() instead of open() (GH-17127) Message-ID: https://github.com/python/cpython/commit/0a8e7fde064c8fb6eb8e78752d4bcdab56643065 commit: 0a8e7fde064c8fb6eb8e78752d4bcdab56643065 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T15:09:03-08:00 summary: bpo-38723: Pdb._runscript should use io.open_code() instead of open() (GH-17127) Co-Authored-By: Brandt Bucher (cherry picked from commit d593881505c1f4acfd17f41312b27cc898451816) Co-authored-by: jsnklln files: A Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst M Lib/pdb.py diff --git a/Lib/pdb.py b/Lib/pdb.py index 8639204891cb0..bf503f1e73ee1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -68,6 +68,7 @@ # commands and is appended to __doc__ after the class has been defined. import os +import io import re import sys import cmd @@ -1565,7 +1566,7 @@ def _runscript(self, filename): self._wait_for_mainpyfile = True self.mainpyfile = self.canonic(filename) self._user_requested_quit = False - with open(filename, "rb") as fp: + with io.open_code(filename) as fp: statement = "exec(compile(%r, %r, 'exec'))" % \ (fp.read(), self.mainpyfile) self.run(statement) diff --git a/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst b/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst new file mode 100644 index 0000000000000..c84bb8589d303 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst @@ -0,0 +1 @@ +:mod:`pdb` now uses :meth:`io.open_code` to trigger auditing events. From webhook-mailer at python.org Tue Nov 12 18:34:51 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 12 Nov 2019 23:34:51 -0000 Subject: [Python-checkins] [3.7] closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17137) Message-ID: https://github.com/python/cpython/commit/b8b3e4377ec38c7d64570afabbd0923a51f0666c commit: b8b3e4377ec38c7d64570afabbd0923a51f0666c branch: 3.7 author: Benjamin Peterson committer: GitHub date: 2019-11-12T15:34:43-08:00 summary: [3.7] closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17137) This change, which follows the behavior of C stdio's fdopen and Python 2's file object, allows pipes to be opened in append mode.. (cherry picked from commit 74fa9f723f700a342e582b5ad4b51a2c4801cd1c) files: A Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst M Lib/_pyio.py M Lib/test/test_io.py M Modules/_io/fileio.c diff --git a/Lib/_pyio.py b/Lib/_pyio.py index e81cc5128881f..d2197813450b0 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1543,7 +1543,11 @@ def __init__(self, file, mode='r', closefd=True, opener=None): # For consistent behaviour, we explicitly seek to the # end of file (otherwise, it might be done only on the # first write()). - os.lseek(fd, 0, SEEK_END) + try: + os.lseek(fd, 0, SEEK_END) + except OSError as e: + if e.errno != errno.ESPIPE: + raise except: if owned_fd is not None: os.close(owned_fd) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index d6bf43d0a0c1d..42002b9acfb76 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3830,6 +3830,17 @@ def test_attributes(self): f.close() g.close() + def test_open_pipe_with_append(self): + # bpo-27805: Ignore ESPIPE from lseek() in open(). + r, w = os.pipe() + self.addCleanup(os.close, r) + f = self.open(w, 'a') + self.addCleanup(f.close) + # Check that the file is marked non-seekable. On Windows, however, lseek + # somehow succeeds on pipes. + if sys.platform != 'win32': + self.assertFalse(f.seekable()) + def test_io_after_close(self): for kwargs in [ {"mode": "w"}, diff --git a/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst new file mode 100644 index 0000000000000..37be6a5d0b22b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst @@ -0,0 +1,2 @@ +Allow opening pipes and other non-seekable files in append mode with +:func:`open`. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 8bbe1ce367e26..ac670510f95dd 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -3,6 +3,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" +#include #ifdef HAVE_SYS_TYPES_H #include #endif @@ -74,7 +75,7 @@ _Py_IDENTIFIER(name); #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ -static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence); +static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); int _PyFileIO_closed(PyObject *self) @@ -475,7 +476,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ - PyObject *pos = portable_lseek(self, NULL, 2); + PyObject *pos = portable_lseek(self, NULL, 2, true); if (pos == NULL) goto error; Py_DECREF(pos); @@ -598,7 +599,7 @@ _io_FileIO_seekable_impl(fileio *self) return err_closed(); if (self->seekable < 0) { /* portable_lseek() sets the seekable attribute */ - PyObject *pos = portable_lseek(self, NULL, SEEK_CUR); + PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); assert(self->seekable >= 0); if (pos == NULL) { PyErr_Clear(); @@ -865,7 +866,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b) /* Cribbed from posix_lseek() */ static PyObject * -portable_lseek(fileio *self, PyObject *posobj, int whence) +portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) { Py_off_t pos, res; int fd = self->fd; @@ -916,8 +917,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence) self->seekable = (res >= 0); } - if (res < 0) - return PyErr_SetFromErrno(PyExc_OSError); + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + return PyErr_SetFromErrno(PyExc_OSError); + } + } #if defined(HAVE_LARGEFILE_SUPPORT) return PyLong_FromLongLong(res); @@ -950,7 +956,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) if (self->fd < 0) return err_closed(); - return portable_lseek(self, pos, whence); + return portable_lseek(self, pos, whence, false); } /*[clinic input] @@ -968,7 +974,7 @@ _io_FileIO_tell_impl(fileio *self) if (self->fd < 0) return err_closed(); - return portable_lseek(self, NULL, 1); + return portable_lseek(self, NULL, 1, false); } #ifdef HAVE_FTRUNCATE @@ -999,7 +1005,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (posobj == Py_None || posobj == NULL) { /* Get the current position. */ - posobj = portable_lseek(self, NULL, 1); + posobj = portable_lseek(self, NULL, 1, false); if (posobj == NULL) return NULL; } From webhook-mailer at python.org Tue Nov 12 18:54:28 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 12 Nov 2019 23:54:28 -0000 Subject: [Python-checkins] [3.8] closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17136) Message-ID: https://github.com/python/cpython/commit/9788f97bf69230ec6b38a483c90e88828eba9a1b commit: 9788f97bf69230ec6b38a483c90e88828eba9a1b branch: 3.8 author: Benjamin Peterson committer: GitHub date: 2019-11-12T15:54:19-08:00 summary: [3.8] closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17136) This change, which follows the behavior of C stdio's fdopen and Python 2's file object, allows pipes to be opened in append mode.. (cherry picked from commit 74fa9f723f700a342e582b5ad4b51a2c4801cd1c) files: A Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst M Lib/_pyio.py M Lib/test/test_io.py M Modules/_io/fileio.c diff --git a/Lib/_pyio.py b/Lib/_pyio.py index eb4e6620fc65f..fd31b8ca9d83f 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1587,7 +1587,11 @@ def __init__(self, file, mode='r', closefd=True, opener=None): # For consistent behaviour, we explicitly seek to the # end of file (otherwise, it might be done only on the # first write()). - os.lseek(fd, 0, SEEK_END) + try: + os.lseek(fd, 0, SEEK_END) + except OSError as e: + if e.errno != errno.ESPIPE: + raise except: if owned_fd is not None: os.close(owned_fd) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index fc474c99053df..50459e0792962 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3907,6 +3907,17 @@ def test_attributes(self): f.close() g.close() + def test_open_pipe_with_append(self): + # bpo-27805: Ignore ESPIPE from lseek() in open(). + r, w = os.pipe() + self.addCleanup(os.close, r) + f = self.open(w, 'a') + self.addCleanup(f.close) + # Check that the file is marked non-seekable. On Windows, however, lseek + # somehow succeeds on pipes. + if sys.platform != 'win32': + self.assertFalse(f.seekable()) + def test_io_after_close(self): for kwargs in [ {"mode": "w"}, diff --git a/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst new file mode 100644 index 0000000000000..37be6a5d0b22b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst @@ -0,0 +1,2 @@ +Allow opening pipes and other non-seekable files in append mode with +:func:`open`. diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 9166c607e737c..482d08f9f23b2 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_object.h" #include "structmember.h" +#include #ifdef HAVE_SYS_TYPES_H #include #endif @@ -75,7 +76,7 @@ _Py_IDENTIFIER(name); #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ -static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence); +static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); int _PyFileIO_closed(PyObject *self) @@ -480,7 +481,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ - PyObject *pos = portable_lseek(self, NULL, 2); + PyObject *pos = portable_lseek(self, NULL, 2, true); if (pos == NULL) goto error; Py_DECREF(pos); @@ -603,7 +604,7 @@ _io_FileIO_seekable_impl(fileio *self) return err_closed(); if (self->seekable < 0) { /* portable_lseek() sets the seekable attribute */ - PyObject *pos = portable_lseek(self, NULL, SEEK_CUR); + PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); assert(self->seekable >= 0); if (pos == NULL) { PyErr_Clear(); @@ -870,7 +871,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b) /* Cribbed from posix_lseek() */ static PyObject * -portable_lseek(fileio *self, PyObject *posobj, int whence) +portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) { Py_off_t pos, res; int fd = self->fd; @@ -921,8 +922,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence) self->seekable = (res >= 0); } - if (res < 0) - return PyErr_SetFromErrno(PyExc_OSError); + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + return PyErr_SetFromErrno(PyExc_OSError); + } + } #if defined(HAVE_LARGEFILE_SUPPORT) return PyLong_FromLongLong(res); @@ -955,7 +961,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) if (self->fd < 0) return err_closed(); - return portable_lseek(self, pos, whence); + return portable_lseek(self, pos, whence, false); } /*[clinic input] @@ -973,7 +979,7 @@ _io_FileIO_tell_impl(fileio *self) if (self->fd < 0) return err_closed(); - return portable_lseek(self, NULL, 1); + return portable_lseek(self, NULL, 1, false); } #ifdef HAVE_FTRUNCATE @@ -1004,7 +1010,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (posobj == Py_None) { /* Get the current position. */ - posobj = portable_lseek(self, NULL, 1); + posobj = portable_lseek(self, NULL, 1, false); if (posobj == NULL) return NULL; } From webhook-mailer at python.org Tue Nov 12 21:33:35 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 13 Nov 2019 02:33:35 -0000 Subject: [Python-checkins] Add Ilya Kulakov to Misc/ACKS. (GH-17130) Message-ID: https://github.com/python/cpython/commit/d6d6e2aa0249bb661541705335ddbb97a53d64c8 commit: d6d6e2aa0249bb661541705335ddbb97a53d64c8 branch: master author: Ilya Kulakov committer: Benjamin Peterson date: 2019-11-12T18:33:04-08:00 summary: Add Ilya Kulakov to Misc/ACKS. (GH-17130) Contributions on bpo-26467 and bpo-29302. files: M Misc/ACKS diff --git a/Misc/ACKS b/Misc/ACKS index 78beee5f34eec..13c6676bace1f 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -910,6 +910,7 @@ Steven Kryskalla Andrew Kuchling Dave Kuhlman Jon Kuhn +Ilya Kulakov Upendra Kumar Toshio Kuratomi Ilia Kurenkov From webhook-mailer at python.org Tue Nov 12 21:40:34 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 02:40:34 -0000 Subject: [Python-checkins] Add Ilya Kulakov to Misc/ACKS. (GH-17130) Message-ID: https://github.com/python/cpython/commit/e5125f7b3b88d8d4814ed7bddbd4f34d24d763dd commit: e5125f7b3b88d8d4814ed7bddbd4f34d24d763dd branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T18:40:30-08:00 summary: Add Ilya Kulakov to Misc/ACKS. (GH-17130) Contributions on bpo-26467 and bpo-29302. (cherry picked from commit d6d6e2aa0249bb661541705335ddbb97a53d64c8) Co-authored-by: Ilya Kulakov files: M Misc/ACKS diff --git a/Misc/ACKS b/Misc/ACKS index 406009c4e2016..a2e8046313f0a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -901,6 +901,7 @@ Steven Kryskalla Andrew Kuchling Dave Kuhlman Jon Kuhn +Ilya Kulakov Upendra Kumar Toshio Kuratomi Ilia Kurenkov From webhook-mailer at python.org Tue Nov 12 22:12:15 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 13 Nov 2019 03:12:15 -0000 Subject: [Python-checkins] Fix minor typos. (GH-17095) Message-ID: https://github.com/python/cpython/commit/2d56af7a94fe7ec0bdf3011652558ae1b889b4a8 commit: 2d56af7a94fe7ec0bdf3011652558ae1b889b4a8 branch: master author: Shu <23287722+susan-shu-c at users.noreply.github.com> committer: Benjamin Peterson date: 2019-11-12T19:12:11-08:00 summary: Fix minor typos. (GH-17095) files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 5cce8ceaa3cb6..c95826305b6a6 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -682,7 +682,7 @@ Before Python loads cached bytecode from ``.pyc`` file, it checks whether the cache is up-to-date with the source ``.py`` file. By default, Python does this by storing the source's last-modified timestamp and size in the cache file when writing it. At runtime, the import system then validates the cache file by -checking the stored metadata in the cache file against at source's +checking the stored metadata in the cache file against the source's metadata. Python also supports "hash-based" cache files, which store a hash of the source @@ -849,7 +849,7 @@ In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the fully qualified name of the module being imported, and the (optional) target module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). @@ -913,7 +913,7 @@ the builtin :func:`__import__` function may be sufficient. This technique may also be employed at the module level to only alter the behaviour of import statements within that module. -To selectively prevent import of some modules from a hook early on the +To selectively prevent the import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ModuleNotFoundError` directly from :meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning From webhook-mailer at python.org Tue Nov 12 22:18:33 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 03:18:33 -0000 Subject: [Python-checkins] Fix minor typos. (GH-17095) Message-ID: https://github.com/python/cpython/commit/2e17b30ee35a1b4e3ffaf8be652d6879ce1a3a08 commit: 2e17b30ee35a1b4e3ffaf8be652d6879ce1a3a08 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T19:18:28-08:00 summary: Fix minor typos. (GH-17095) (cherry picked from commit 2d56af7a94fe7ec0bdf3011652558ae1b889b4a8) Co-authored-by: Shu <23287722+susan-shu-c at users.noreply.github.com> files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 88290c88bb35d..50a7562e3ae7a 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -683,7 +683,7 @@ Before Python loads cached bytecode from ``.pyc`` file, it checks whether the cache is up-to-date with the source ``.py`` file. By default, Python does this by storing the source's last-modified timestamp and size in the cache file when writing it. At runtime, the import system then validates the cache file by -checking the stored metadata in the cache file against at source's +checking the stored metadata in the cache file against the source's metadata. Python also supports "hash-based" cache files, which store a hash of the source @@ -850,7 +850,7 @@ In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the fully qualified name of the module being imported, and the (optional) target module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). @@ -914,7 +914,7 @@ the builtin :func:`__import__` function may be sufficient. This technique may also be employed at the module level to only alter the behaviour of import statements within that module. -To selectively prevent import of some modules from a hook early on the +To selectively prevent the import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ModuleNotFoundError` directly from :meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning From webhook-mailer at python.org Tue Nov 12 22:18:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 03:18:52 -0000 Subject: [Python-checkins] Fix minor typos. (GH-17095) Message-ID: https://github.com/python/cpython/commit/5a3b8d877d6b07f767b51c02dc2d42e6c1a8c41c commit: 5a3b8d877d6b07f767b51c02dc2d42e6c1a8c41c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T19:18:47-08:00 summary: Fix minor typos. (GH-17095) (cherry picked from commit 2d56af7a94fe7ec0bdf3011652558ae1b889b4a8) Co-authored-by: Shu <23287722+susan-shu-c at users.noreply.github.com> files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 0228bfb7e984c..c6f6d030d2ac3 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -682,7 +682,7 @@ Before Python loads cached bytecode from ``.pyc`` file, it checks whether the cache is up-to-date with the source ``.py`` file. By default, Python does this by storing the source's last-modified timestamp and size in the cache file when writing it. At runtime, the import system then validates the cache file by -checking the stored metadata in the cache file against at source's +checking the stored metadata in the cache file against the source's metadata. Python also supports "hash-based" cache files, which store a hash of the source @@ -849,7 +849,7 @@ In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two arguments: the fully qualified name of the module being imported, and the (optional) target module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). @@ -913,7 +913,7 @@ the builtin :func:`__import__` function may be sufficient. This technique may also be employed at the module level to only alter the behaviour of import statements within that module. -To selectively prevent import of some modules from a hook early on the +To selectively prevent the import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ModuleNotFoundError` directly from :meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning From webhook-mailer at python.org Wed Nov 13 02:13:38 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Wed, 13 Nov 2019 07:13:38 -0000 Subject: [Python-checkins] bpo-4630: Add cursor no-blink option for IDLE (GH-16960) Message-ID: https://github.com/python/cpython/commit/9c2844927d15b2d3e21b28d62249dead02b5b597 commit: 9c2844927d15b2d3e21b28d62249dead02b5b597 branch: master author: Zackery Spytz committer: Terry Jan Reedy date: 2019-11-13T02:13:33-05:00 summary: bpo-4630: Add cursor no-blink option for IDLE (GH-16960) This immediately toggles shell, editor, and output windows, but does not affect other input widgets. files: A Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/config-main.def M Lib/idlelib/config.py M Lib/idlelib/configdialog.py M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 938c9c7d06b05..b02a9880505e8 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,11 @@ Released on 2020-10-05? ====================================== -bop-26353: Stop adding newline when saving an IDLE shell window. +bpo-4360: Add an option to toggle IDLE's cursor blink for shell, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zachary Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index b2be6250d021a..28ae94161d5c0 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -59,6 +59,7 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 +cursor-blink= 1 font= TkFixedFont # For TkFixedFont, the actual size and boldness are obtained from tk # and override 10 and 0. See idlelib.config.IdleConf.GetFont diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 12e6f9fae78b8..04444a3bf20b3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -158,6 +158,8 @@ def __init__(self, _utest=False): self.defaultCfg = {} self.userCfg = {} self.cfg = {} # TODO use to select userCfg vs defaultCfg + # self.blink_off_time = ['insertofftime'] + # See https:/bugs.python.org/issue4630, msg356516. if not _utest: self.CreateConfigHandlers() diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index df216582fe609..aaf319bbe1bef 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -236,6 +236,7 @@ def activate_config_changes(self): instance.set_notabs_indentwidth() instance.ApplyKeybindings() instance.reset_help_menu_entries() + instance.update_cursor_blink() for klass in reloadables: klass.reload() @@ -1820,6 +1821,9 @@ def create_page_general(self): (*)win_width_int: Entry - win_width win_height_title: Label (*)win_height_int: Entry - win_height + frame_cursor_blink: Frame + cursor_blink_title: Label + (*)cursor_blink_bool: Checkbutton - cursor_blink frame_autocomplete: Frame auto_wait_title: Label (*)auto_wait_int: Entry - autocomplete_wait @@ -1864,6 +1868,8 @@ def create_page_general(self): StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.cursor_blink = tracers.add( + BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink')) self.autocomplete_wait = tracers.add( StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) self.paren_style = tracers.add( @@ -1920,6 +1926,11 @@ def create_page_general(self): validatecommand=self.digits_only, validate='key', ) + frame_cursor_blink = Frame(frame_window, borderwidth=0) + cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink') + self.cursor_blink_bool = Checkbutton(frame_cursor_blink, + variable=self.cursor_blink, width=1) + frame_autocomplete = Frame(frame_window, borderwidth=0,) auto_wait_title = Label(frame_autocomplete, text='Completions Popup Wait (milliseconds)') @@ -2024,6 +2035,10 @@ def create_page_general(self): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_cursor_blink. + frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X) + cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5) # frame_autocomplete. frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) @@ -2078,6 +2093,8 @@ def load_general_cfg(self): 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.cursor_blink.set(idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool')) self.autocomplete_wait.set(idleConf.GetOption( 'extensions', 'AutoComplete', 'popupwait', type='int')) self.paren_style.set(idleConf.GetOption( diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index adeed74059f84..dff104ff0f18f 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -241,6 +241,12 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() + # Store the current value of the insertofftime now so we can restore + # it if needed. + if not hasattr(idleConf, 'blink_off_time'): + idleConf.blink_off_time = self.text['insertofftime'] + self.update_cursor_blink() + # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -803,6 +809,16 @@ def colorize_syntax_error(self, text, pos): text.mark_set("insert", pos + "+1c") text.see(pos) + def update_cursor_blink(self): + "Update the cursor blink configuration." + cursorblink = idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool') + if not cursorblink: + self.text['insertofftime'] = 0 + else: + # Restore the original value + self.text['insertofftime'] = idleConf.blink_off_time + def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configdialog.py diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 37e83439c471e..1f14ed1f26473 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1135,6 +1135,10 @@ def test_editor_size(self): d.win_width_int.insert(0, '11') self.assertEqual(mainpage, {'EditorWindow': {'width': '11'}}) + def test_cursor_blink(self): + self.page.cursor_blink_bool.invoke() + self.assertEqual(mainpage, {'EditorWindow': {'cursor-blink': 'False'}}) + def test_autocomplete_wait(self): self.page.auto_wait_int.delete(0, 'end') self.page.auto_wait_int.insert(0, '11') diff --git a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst new file mode 100644 index 0000000000000..759b35b77fb8d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst @@ -0,0 +1,3 @@ +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. +Patch by Zachary Spytz. From webhook-mailer at python.org Wed Nov 13 02:36:47 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 07:36:47 -0000 Subject: [Python-checkins] bpo-4630: Add cursor no-blink option for IDLE (GH-16960) Message-ID: https://github.com/python/cpython/commit/a67bc10e42fa9a077eb4d9d7bd767c3efddbc366 commit: a67bc10e42fa9a077eb4d9d7bd767c3efddbc366 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T23:36:42-08:00 summary: bpo-4630: Add cursor no-blink option for IDLE (GH-16960) This immediately toggles shell, editor, and output windows, but does not affect other input widgets. (cherry picked from commit 9c2844927d15b2d3e21b28d62249dead02b5b597) Co-authored-by: Zackery Spytz files: A Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/config-main.def M Lib/idlelib/config.py M Lib/idlelib/configdialog.py M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 5e6686a89e44d..fba936982616c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,11 @@ Released on 2019-12-16? ====================================== -bop-26353: Stop adding newline when saving an IDLE shell window. +bpo-4360: Add an option to toggle IDLE's cursor blink for shell, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zachary Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index b2be6250d021a..28ae94161d5c0 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -59,6 +59,7 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 +cursor-blink= 1 font= TkFixedFont # For TkFixedFont, the actual size and boldness are obtained from tk # and override 10 and 0. See idlelib.config.IdleConf.GetFont diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 12e6f9fae78b8..04444a3bf20b3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -158,6 +158,8 @@ def __init__(self, _utest=False): self.defaultCfg = {} self.userCfg = {} self.cfg = {} # TODO use to select userCfg vs defaultCfg + # self.blink_off_time = ['insertofftime'] + # See https:/bugs.python.org/issue4630, msg356516. if not _utest: self.CreateConfigHandlers() diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index df216582fe609..aaf319bbe1bef 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -236,6 +236,7 @@ def activate_config_changes(self): instance.set_notabs_indentwidth() instance.ApplyKeybindings() instance.reset_help_menu_entries() + instance.update_cursor_blink() for klass in reloadables: klass.reload() @@ -1820,6 +1821,9 @@ def create_page_general(self): (*)win_width_int: Entry - win_width win_height_title: Label (*)win_height_int: Entry - win_height + frame_cursor_blink: Frame + cursor_blink_title: Label + (*)cursor_blink_bool: Checkbutton - cursor_blink frame_autocomplete: Frame auto_wait_title: Label (*)auto_wait_int: Entry - autocomplete_wait @@ -1864,6 +1868,8 @@ def create_page_general(self): StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.cursor_blink = tracers.add( + BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink')) self.autocomplete_wait = tracers.add( StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) self.paren_style = tracers.add( @@ -1920,6 +1926,11 @@ def create_page_general(self): validatecommand=self.digits_only, validate='key', ) + frame_cursor_blink = Frame(frame_window, borderwidth=0) + cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink') + self.cursor_blink_bool = Checkbutton(frame_cursor_blink, + variable=self.cursor_blink, width=1) + frame_autocomplete = Frame(frame_window, borderwidth=0,) auto_wait_title = Label(frame_autocomplete, text='Completions Popup Wait (milliseconds)') @@ -2024,6 +2035,10 @@ def create_page_general(self): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_cursor_blink. + frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X) + cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5) # frame_autocomplete. frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) @@ -2078,6 +2093,8 @@ def load_general_cfg(self): 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.cursor_blink.set(idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool')) self.autocomplete_wait.set(idleConf.GetOption( 'extensions', 'AutoComplete', 'popupwait', type='int')) self.paren_style.set(idleConf.GetOption( diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index adeed74059f84..dff104ff0f18f 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -241,6 +241,12 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() + # Store the current value of the insertofftime now so we can restore + # it if needed. + if not hasattr(idleConf, 'blink_off_time'): + idleConf.blink_off_time = self.text['insertofftime'] + self.update_cursor_blink() + # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -803,6 +809,16 @@ def colorize_syntax_error(self, text, pos): text.mark_set("insert", pos + "+1c") text.see(pos) + def update_cursor_blink(self): + "Update the cursor blink configuration." + cursorblink = idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool') + if not cursorblink: + self.text['insertofftime'] = 0 + else: + # Restore the original value + self.text['insertofftime'] = idleConf.blink_off_time + def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configdialog.py diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 37e83439c471e..1f14ed1f26473 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1135,6 +1135,10 @@ def test_editor_size(self): d.win_width_int.insert(0, '11') self.assertEqual(mainpage, {'EditorWindow': {'width': '11'}}) + def test_cursor_blink(self): + self.page.cursor_blink_bool.invoke() + self.assertEqual(mainpage, {'EditorWindow': {'cursor-blink': 'False'}}) + def test_autocomplete_wait(self): self.page.auto_wait_int.delete(0, 'end') self.page.auto_wait_int.insert(0, '11') diff --git a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst new file mode 100644 index 0000000000000..759b35b77fb8d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst @@ -0,0 +1,3 @@ +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. +Patch by Zachary Spytz. From webhook-mailer at python.org Wed Nov 13 02:37:11 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 07:37:11 -0000 Subject: [Python-checkins] bpo-4630: Add cursor no-blink option for IDLE (GH-16960) Message-ID: https://github.com/python/cpython/commit/753d0c05b39f21d5987d59d7fe8b5a6d721bc22c commit: 753d0c05b39f21d5987d59d7fe8b5a6d721bc22c branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-12T23:37:07-08:00 summary: bpo-4630: Add cursor no-blink option for IDLE (GH-16960) This immediately toggles shell, editor, and output windows, but does not affect other input widgets. (cherry picked from commit 9c2844927d15b2d3e21b28d62249dead02b5b597) Co-authored-by: Zackery Spytz files: A Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/config-main.def M Lib/idlelib/config.py M Lib/idlelib/configdialog.py M Lib/idlelib/editor.py M Lib/idlelib/idle_test/test_configdialog.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 81bf746a5cba3..2fd2ea19b5a0f 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,7 +3,11 @@ Released on 2019-12-16? ====================================== -bop-26353: Stop adding newline when saving an IDLE shell window. +bpo-4360: Add an option to toggle IDLE's cursor blink for shell, +editor, and output windows. See Settings, General, Window Preferences, +Cursor Blink. Patch by Zachary Spytz. + +bpo-26353: Stop adding newline when saving an IDLE shell window. bpo-38598: Do not try to compile IDLE shell or output windows. diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index b2be6250d021a..28ae94161d5c0 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -59,6 +59,7 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 +cursor-blink= 1 font= TkFixedFont # For TkFixedFont, the actual size and boldness are obtained from tk # and override 10 and 0. See idlelib.config.IdleConf.GetFont diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index 12e6f9fae78b8..04444a3bf20b3 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -158,6 +158,8 @@ def __init__(self, _utest=False): self.defaultCfg = {} self.userCfg = {} self.cfg = {} # TODO use to select userCfg vs defaultCfg + # self.blink_off_time = ['insertofftime'] + # See https:/bugs.python.org/issue4630, msg356516. if not _utest: self.CreateConfigHandlers() diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index df216582fe609..aaf319bbe1bef 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -236,6 +236,7 @@ def activate_config_changes(self): instance.set_notabs_indentwidth() instance.ApplyKeybindings() instance.reset_help_menu_entries() + instance.update_cursor_blink() for klass in reloadables: klass.reload() @@ -1820,6 +1821,9 @@ def create_page_general(self): (*)win_width_int: Entry - win_width win_height_title: Label (*)win_height_int: Entry - win_height + frame_cursor_blink: Frame + cursor_blink_title: Label + (*)cursor_blink_bool: Checkbutton - cursor_blink frame_autocomplete: Frame auto_wait_title: Label (*)auto_wait_int: Entry - autocomplete_wait @@ -1864,6 +1868,8 @@ def create_page_general(self): StringVar(self), ('main', 'EditorWindow', 'width')) self.win_height = tracers.add( StringVar(self), ('main', 'EditorWindow', 'height')) + self.cursor_blink = tracers.add( + BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink')) self.autocomplete_wait = tracers.add( StringVar(self), ('extensions', 'AutoComplete', 'popupwait')) self.paren_style = tracers.add( @@ -1920,6 +1926,11 @@ def create_page_general(self): validatecommand=self.digits_only, validate='key', ) + frame_cursor_blink = Frame(frame_window, borderwidth=0) + cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink') + self.cursor_blink_bool = Checkbutton(frame_cursor_blink, + variable=self.cursor_blink, width=1) + frame_autocomplete = Frame(frame_window, borderwidth=0,) auto_wait_title = Label(frame_autocomplete, text='Completions Popup Wait (milliseconds)') @@ -2024,6 +2035,10 @@ def create_page_general(self): win_height_title.pack(side=RIGHT, anchor=E, pady=5) self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5) win_width_title.pack(side=RIGHT, anchor=E, pady=5) + # frame_cursor_blink. + frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X) + cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5) + self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5) # frame_autocomplete. frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X) auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5) @@ -2078,6 +2093,8 @@ def load_general_cfg(self): 'main', 'EditorWindow', 'width', type='int')) self.win_height.set(idleConf.GetOption( 'main', 'EditorWindow', 'height', type='int')) + self.cursor_blink.set(idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool')) self.autocomplete_wait.set(idleConf.GetOption( 'extensions', 'AutoComplete', 'popupwait', type='int')) self.paren_style.set(idleConf.GetOption( diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index adeed74059f84..dff104ff0f18f 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -241,6 +241,12 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() + # Store the current value of the insertofftime now so we can restore + # it if needed. + if not hasattr(idleConf, 'blink_off_time'): + idleConf.blink_off_time = self.text['insertofftime'] + self.update_cursor_blink() + # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -803,6 +809,16 @@ def colorize_syntax_error(self, text, pos): text.mark_set("insert", pos + "+1c") text.see(pos) + def update_cursor_blink(self): + "Update the cursor blink configuration." + cursorblink = idleConf.GetOption( + 'main', 'EditorWindow', 'cursor-blink', type='bool') + if not cursorblink: + self.text['insertofftime'] = 0 + else: + # Restore the original value + self.text['insertofftime'] = idleConf.blink_off_time + def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configdialog.py diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 37e83439c471e..1f14ed1f26473 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1135,6 +1135,10 @@ def test_editor_size(self): d.win_width_int.insert(0, '11') self.assertEqual(mainpage, {'EditorWindow': {'width': '11'}}) + def test_cursor_blink(self): + self.page.cursor_blink_bool.invoke() + self.assertEqual(mainpage, {'EditorWindow': {'cursor-blink': 'False'}}) + def test_autocomplete_wait(self): self.page.auto_wait_int.delete(0, 'end') self.page.auto_wait_int.insert(0, '11') diff --git a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst new file mode 100644 index 0000000000000..759b35b77fb8d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst @@ -0,0 +1,3 @@ +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. +Patch by Zachary Spytz. From webhook-mailer at python.org Wed Nov 13 11:14:21 2019 From: webhook-mailer at python.org (Tal Einat) Date: Wed, 13 Nov 2019 16:14:21 -0000 Subject: [Python-checkins] bpo-38786: Add parsing of https links to pydoc (GH-17143) Message-ID: https://github.com/python/cpython/commit/61289d436661025a3111065482275d49a4850b8d commit: 61289d436661025a3111065482275d49a4850b8d branch: master author: Kirill committer: Tal Einat date: 2019-11-13T18:13:52+02:00 summary: bpo-38786: Add parsing of https links to pydoc (GH-17143) files: A Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst M Lib/pydoc.py M Lib/test/test_pydoc.py M Lib/xmlrpc/server.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 9a22e56686f61..e32fdf76978e2 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -585,7 +585,7 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): escape = escape or self.escape results = [] here = 0 - pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|' + pattern = re.compile(r'\b((http|https|ftp)://\S+[\w/]|' r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?(\w+))') diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index c80477c50f098..b803b8bff2f7f 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -1311,6 +1311,17 @@ def test_async_generator_annotation(self): 'async an_async_generator', html) + def test_html_for_https_links(self): + def a_fn_with_https_link(): + """a link https://localhost/""" + pass + + html = pydoc.HTMLDoc().document(a_fn_with_https_link) + self.assertIn( + 'https://localhost/', + html + ) + class PydocServerTest(unittest.TestCase): """Tests for pydoc._start_server""" diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index 32aba4df4c7eb..287e3243b10cc 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -732,7 +732,7 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): # hyperlinking of arbitrary strings being used as method # names. Only methods with names consisting of word characters # and '.'s are hyperlinked. - pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|' + pattern = re.compile(r'\b((http|https|ftp)://\S+[\w/]|' r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?((?:\w|\.)+))\b') diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst b/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst new file mode 100644 index 0000000000000..f95d773e08c50 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst @@ -0,0 +1 @@ +pydoc now recognizes and parses HTTPS URLs. Patch by python273. From webhook-mailer at python.org Wed Nov 13 16:37:16 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 21:37:16 -0000 Subject: [Python-checkins] bpo-38785: Prevent asyncio from crashing (GH-17144) Message-ID: https://github.com/python/cpython/commit/dad6be5ffe48beb74fad78cf758b886afddc7aed commit: dad6be5ffe48beb74fad78cf758b886afddc7aed branch: master author: Andrew Svetlov committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-13T13:36:46-08:00 summary: bpo-38785: Prevent asyncio from crashing (GH-17144) if parent `__init__` is not called from a constructor of object derived from `asyncio.Future` https://bugs.python.org/issue38785 files: A Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst M Lib/asyncio/futures.py M Lib/test/test_asyncio/test_futures.py M Modules/_asynciomodule.c diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 98a5308ed0618..9afda220bd78f 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -115,7 +115,10 @@ def _log_traceback(self, val): def get_loop(self): """Return the event loop the Future is bound to.""" - return self._loop + loop = self._loop + if loop is None: + raise RuntimeError("Future object is not initialized.") + return loop def cancel(self): """Cancel the future and schedule callbacks. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 2e4583d12450c..ee5edd5bd311f 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -822,5 +822,44 @@ def _new_future(self): return futures._PyFuture(loop=self.loop) +class BaseFutureInheritanceTests: + + def _get_future_cls(self): + raise NotImplementedError + + def setUp(self): + super().setUp() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + + def test_inherit_without_calling_super_init(self): + # See https://bugs.python.org/issue38785 for the context + cls = self._get_future_cls() + + class MyFut(cls): + def __init__(self, *args, **kwargs): + # don't call super().__init__() + pass + + fut = MyFut(loop=self.loop) + with self.assertRaisesRegex( + RuntimeError, + "Future object is not initialized." + ): + fut.get_loop() + + +class PyFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._PyFuture + + +class CFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._CFuture + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst new file mode 100644 index 0000000000000..49e9937998081 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst @@ -0,0 +1,2 @@ +Prevent asyncio from crashing if parent ``__init__`` is not called from a +constructor of object derived from ``asyncio.Future``. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 89b2fdea0f632..5e1bcfbde247c 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1091,6 +1091,7 @@ static PyObject * _asyncio_Future_get_loop_impl(FutureObj *self) /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ { + ENSURE_FUTURE_ALIVE(self) Py_INCREF(self->fut_loop); return self->fut_loop; } From webhook-mailer at python.org Wed Nov 13 16:54:59 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 21:54:59 -0000 Subject: [Python-checkins] bpo-38785: Prevent asyncio from crashing (GH-17144) Message-ID: https://github.com/python/cpython/commit/87b4d3994e4f81d6e39a5e86c1b7040df065ea37 commit: 87b4d3994e4f81d6e39a5e86c1b7040df065ea37 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-13T13:54:50-08:00 summary: bpo-38785: Prevent asyncio from crashing (GH-17144) if parent `__init__` is not called from a constructor of object derived from `asyncio.Future` https://bugs.python.org/issue38785 (cherry picked from commit dad6be5ffe48beb74fad78cf758b886afddc7aed) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst M Lib/asyncio/futures.py M Lib/test/test_asyncio/test_futures.py M Modules/_asynciomodule.c diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 0e0e696a25354..1bd6c81406fa2 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -118,7 +118,10 @@ def _log_traceback(self, val): def get_loop(self): """Return the event loop the Future is bound to.""" - return self._loop + loop = self._loop + if loop is None: + raise RuntimeError("Future object is not initialized.") + return loop def cancel(self): """Cancel the future and schedule callbacks. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 9608a3a81cc33..8bc861d3740f7 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -818,5 +818,44 @@ def _new_future(self): return futures._PyFuture(loop=self.loop) +class BaseFutureInheritanceTests: + + def _get_future_cls(self): + raise NotImplementedError + + def setUp(self): + super().setUp() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + + def test_inherit_without_calling_super_init(self): + # See https://bugs.python.org/issue38785 for the context + cls = self._get_future_cls() + + class MyFut(cls): + def __init__(self, *args, **kwargs): + # don't call super().__init__() + pass + + fut = MyFut(loop=self.loop) + with self.assertRaisesRegex( + RuntimeError, + "Future object is not initialized." + ): + fut.get_loop() + + +class PyFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._PyFuture + + +class CFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._CFuture + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst new file mode 100644 index 0000000000000..49e9937998081 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst @@ -0,0 +1,2 @@ +Prevent asyncio from crashing if parent ``__init__`` is not called from a +constructor of object derived from ``asyncio.Future``. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 35264f5815c3b..62173994a6ec9 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1089,6 +1089,7 @@ static PyObject * _asyncio_Future_get_loop_impl(FutureObj *self) /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ { + ENSURE_FUTURE_ALIVE(self) Py_INCREF(self->fut_loop); return self->fut_loop; } From webhook-mailer at python.org Wed Nov 13 16:55:00 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 13 Nov 2019 21:55:00 -0000 Subject: [Python-checkins] bpo-38785: Prevent asyncio from crashing (GH-17144) Message-ID: https://github.com/python/cpython/commit/694c03fabb5cf3df0102cc317670a10fc39c6786 commit: 694c03fabb5cf3df0102cc317670a10fc39c6786 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-13T13:54:56-08:00 summary: bpo-38785: Prevent asyncio from crashing (GH-17144) if parent `__init__` is not called from a constructor of object derived from `asyncio.Future` https://bugs.python.org/issue38785 (cherry picked from commit dad6be5ffe48beb74fad78cf758b886afddc7aed) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst M Lib/asyncio/futures.py M Lib/test/test_asyncio/test_futures.py M Modules/_asynciomodule.c diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 98a5308ed0618..9afda220bd78f 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -115,7 +115,10 @@ def _log_traceback(self, val): def get_loop(self): """Return the event loop the Future is bound to.""" - return self._loop + loop = self._loop + if loop is None: + raise RuntimeError("Future object is not initialized.") + return loop def cancel(self): """Cancel the future and schedule callbacks. diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 2e4583d12450c..ee5edd5bd311f 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -822,5 +822,44 @@ def _new_future(self): return futures._PyFuture(loop=self.loop) +class BaseFutureInheritanceTests: + + def _get_future_cls(self): + raise NotImplementedError + + def setUp(self): + super().setUp() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + + def test_inherit_without_calling_super_init(self): + # See https://bugs.python.org/issue38785 for the context + cls = self._get_future_cls() + + class MyFut(cls): + def __init__(self, *args, **kwargs): + # don't call super().__init__() + pass + + fut = MyFut(loop=self.loop) + with self.assertRaisesRegex( + RuntimeError, + "Future object is not initialized." + ): + fut.get_loop() + + +class PyFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._PyFuture + + +class CFutureInheritanceTests(BaseFutureInheritanceTests, + test_utils.TestCase): + def _get_future_cls(self): + return futures._CFuture + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst new file mode 100644 index 0000000000000..49e9937998081 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst @@ -0,0 +1,2 @@ +Prevent asyncio from crashing if parent ``__init__`` is not called from a +constructor of object derived from ``asyncio.Future``. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5261ed3d4c3d0..88b834c113322 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1092,6 +1092,7 @@ static PyObject * _asyncio_Future_get_loop_impl(FutureObj *self) /*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ { + ENSURE_FUTURE_ALIVE(self) Py_INCREF(self->fut_loop); return self->fut_loop; } From webhook-mailer at python.org Wed Nov 13 22:09:16 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Thu, 14 Nov 2019 03:09:16 -0000 Subject: [Python-checkins] closes bpo-38692: Add a pidfd child process watcher to asyncio. (GH-17069) Message-ID: https://github.com/python/cpython/commit/3ccdd9b180f9a3f29c8ddc8ad1b331fe8df26519 commit: 3ccdd9b180f9a3f29c8ddc8ad1b331fe8df26519 branch: master author: Benjamin Peterson committer: GitHub date: 2019-11-13T19:08:50-08:00 summary: closes bpo-38692: Add a pidfd child process watcher to asyncio. (GH-17069) files: A Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst M Doc/library/asyncio-policy.rst M Doc/whatsnew/3.9.rst M Lib/asyncio/unix_events.py M Lib/test/test_asyncio/test_subprocess.py diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst index aa8f8f13eae02..d9d3232d2408b 100644 --- a/Doc/library/asyncio-policy.rst +++ b/Doc/library/asyncio-policy.rst @@ -257,6 +257,18 @@ implementation used by the asyncio event loop: This solution requires a running event loop in the main thread to work, as :class:`SafeChildWatcher`. +.. class:: PidfdChildWatcher + + This implementation polls process file descriptors (pidfds) to await child + process termination. In some respects, :class:`PidfdChildWatcher` is a + "Goldilocks" child watcher implementation. It doesn't require signals or + threads, doesn't interfere with any processes launched outside the event + loop, and scales linearly with the number of subprocesses launched by the + event loop. The main disadvantage is that pidfds are specific to Linux, and + only work on recent (5.3+) kernels. + + .. versionadded:: 3.9 + Custom Policies =============== diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 1cd21c6ab8f71..b1beb0be090cf 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -130,6 +130,9 @@ that schedules a shutdown for the default executor that waits on the :func:`asyncio.run` has been updated to use the new :term:`coroutine`. (Contributed by Kyle Stanley in :issue:`34037`.) +Added :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher +implementation that polls process file descriptors. (:issue:`38692`) + curses ------ diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index d8f653045aee4..d02460c004376 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -878,6 +878,73 @@ def __exit__(self, a, b, c): raise NotImplementedError() +class PidfdChildWatcher(AbstractChildWatcher): + """Child watcher implementation using Linux's pid file descriptors. + + This child watcher polls process file descriptors (pidfds) to await child + process termination. In some respects, PidfdChildWatcher is a "Goldilocks" + child watcher implementation. It doesn't require signals or threads, doesn't + interfere with any processes launched outside the event loop, and scales + linearly with the number of subprocesses launched by the event loop. The + main disadvantage is that pidfds are specific to Linux, and only work on + recent (5.3+) kernels. + """ + + def __init__(self): + self._loop = None + self._callbacks = {} + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, exc_traceback): + pass + + def is_active(self): + return self._loop is not None and self._loop.is_running() + + def close(self): + self.attach_loop(None) + + def attach_loop(self, loop): + if self._loop is not None and loop is None and self._callbacks: + warnings.warn( + 'A loop is being detached ' + 'from a child watcher with pending handlers', + RuntimeWarning) + for pidfd, _, _ in self._callbacks.values(): + self._loop._remove_reader(pidfd) + os.close(pidfd) + self._callbacks.clear() + self._loop = loop + + def add_child_handler(self, pid, callback, *args): + existing = self._callbacks.get(pid) + if existing is not None: + self._callbacks[pid] = existing[0], callback, args + else: + pidfd = os.pidfd_open(pid) + self._loop._add_reader(pidfd, self._do_wait, pid) + self._callbacks[pid] = pidfd, callback, args + + def _do_wait(self, pid): + pidfd, callback, args = self._callbacks.pop(pid) + self._loop._remove_reader(pidfd) + _, status = os.waitpid(pid, 0) + os.close(pidfd) + returncode = _compute_returncode(status) + callback(pid, returncode, *args) + + def remove_child_handler(self, pid): + try: + pidfd, _, _ = self._callbacks.pop(pid) + except KeyError: + return False + self._loop._remove_reader(pidfd) + os.close(pidfd) + return True + + def _compute_returncode(status): if os.WIFSIGNALED(status): # The child process died because of a signal. diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 17552d03f5f04..a6c3acc420ac7 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -1,3 +1,4 @@ +import os import signal import sys import unittest @@ -691,6 +692,23 @@ class SubprocessFastWatcherTests(SubprocessWatcherMixin, Watcher = unix_events.FastChildWatcher + def has_pidfd_support(): + if not hasattr(os, 'pidfd_open'): + return False + try: + os.close(os.pidfd_open(os.getpid())) + except OSError: + return False + return True + + @unittest.skipUnless( + has_pidfd_support(), + "operating system does not support pidfds", + ) + class SubprocessPidfdWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + Watcher = unix_events.PidfdChildWatcher + else: # Windows class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst b/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst new file mode 100644 index 0000000000000..7c8b3e8d74ee7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst @@ -0,0 +1,2 @@ +Add :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher +implementation that polls process file descriptors. From webhook-mailer at python.org Thu Nov 14 06:20:52 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 14 Nov 2019 11:20:52 -0000 Subject: [Python-checkins] bpo-38644: Add _PyEval_EvalFrame() with tstate (GH-17131) Message-ID: https://github.com/python/cpython/commit/b9e681261cd5ce6db0a79461c58d7cc52cfa4902 commit: b9e681261cd5ce6db0a79461c58d7cc52cfa4902 branch: master author: Victor Stinner committer: GitHub date: 2019-11-14T12:20:46+01:00 summary: bpo-38644: Add _PyEval_EvalFrame() with tstate (GH-17131) Add _PyEval_EvalFrame() static inline function to get eval_frame from tstate->interp. files: M Include/internal/pycore_ceval.h M Objects/call.c M Objects/genobject.c M Python/ceval.c diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index f20e4ebb7b18c..7adb87214a058 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -11,6 +11,9 @@ extern "C" { /* Forward declarations */ struct pyruntimestate; struct _ceval_runtime_state; +struct _frame; + +#include "pycore_pystate.h" /* PyInterpreterState.eval_frame */ PyAPI_FUNC(void) _Py_FinishPendingCalls(struct pyruntimestate *runtime); PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *); @@ -34,6 +37,12 @@ PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( /* Private function */ void _PyEval_Fini(void); +static inline PyObject* +_PyEval_EvalFrame(PyThreadState *tstate, struct _frame *f, int throwflag) +{ + return tstate->interp->eval_frame(f, throwflag); +} + #ifdef __cplusplus } #endif diff --git a/Objects/call.c b/Objects/call.c index a8ae41a7842ae..96174c4e331e7 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_ceval.h" /* _PyEval_EvalFrame() */ #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" @@ -303,7 +304,7 @@ function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs Py_INCREF(*args); fastlocals[i] = *args++; } - PyObject *result = PyEval_EvalFrameEx(f, 0); + PyObject *result = _PyEval_EvalFrame(tstate, f, 0); if (Py_REFCNT(f) > 1) { Py_DECREF(f); diff --git a/Objects/genobject.c b/Objects/genobject.c index b72248caf9cc7..98eb9c34c3dcd 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1,6 +1,7 @@ /* Generator object implementation */ #include "Python.h" +#include "pycore_ceval.h" /* _PyEval_EvalFrame() */ #include "pycore_object.h" #include "pycore_pystate.h" #include "frameobject.h" @@ -219,7 +220,7 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) gen->gi_running = 1; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; - result = PyEval_EvalFrameEx(f, exc); + result = _PyEval_EvalFrame(tstate, f, exc); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; gen->gi_running = 0; diff --git a/Python/ceval.c b/Python/ceval.c index 4d8f1b913c530..046cd69151b4e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -722,18 +722,20 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) /* Interpreter main loop */ PyObject * -PyEval_EvalFrame(PyFrameObject *f) { +PyEval_EvalFrame(PyFrameObject *f) +{ /* This is for backward compatibility with extension modules that used this API; core interpreter code should call PyEval_EvalFrameEx() */ - return PyEval_EvalFrameEx(f, 0); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_EvalFrame(tstate, f, 0); } PyObject * PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) { - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - return interp->eval_frame(f, throwflag); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_EvalFrame(tstate, f, throwflag); } PyObject* _Py_HOT_FUNCTION @@ -4295,7 +4297,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, return gen; } - retval = PyEval_EvalFrameEx(f,0); + retval = _PyEval_EvalFrame(tstate, f, 0); fail: /* Jump here from prelude on failure */ From webhook-mailer at python.org Thu Nov 14 07:36:30 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 14 Nov 2019 12:36:30 -0000 Subject: [Python-checkins] bpo-38644: Add _PyObject_Call() (GH-17089) Message-ID: https://github.com/python/cpython/commit/4d231bcc77ac8ce7d11bda0804130dcdd678f710 commit: 4d231bcc77ac8ce7d11bda0804130dcdd678f710 branch: master author: Victor Stinner committer: GitHub date: 2019-11-14T13:36:21+01:00 summary: bpo-38644: Add _PyObject_Call() (GH-17089) * Add pycore_call.h internal header file. * Add _PyObject_Call(): PyObject_Call() with tstate * Add _PyObject_CallNoArgTstate(): _PyObject_CallNoArg() with tstate * Add _PyObject_FastCallDictTstate(): _PyObject_FastCallDict() with tstate * _PyObject_Call_Prepend() now takes tstate * Replace _PyObject_FastCall() calls with _PyObject_VectorcallTstate() calls files: A Include/internal/pycore_call.h M Include/cpython/abstract.h M Makefile.pre.in M Objects/call.c M Objects/typeobject.c M PCbuild/pythoncore.vcxproj M PCbuild/pythoncore.vcxproj.filters M Python/_warnings.c M Python/bltinmodule.c M Python/ceval.c diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index fef538e63e042..2c4eae70b9690 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -137,7 +137,8 @@ PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, Py static inline PyObject * _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) { - return _PyObject_Vectorcall(func, args, (size_t)nargs, NULL); + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); } /* Call a callable without any arguments @@ -145,7 +146,8 @@ _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) PyObject_CallNoArgs(). */ static inline PyObject * _PyObject_CallNoArg(PyObject *func) { - return _PyObject_Vectorcall(func, NULL, 0, NULL); + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } static inline PyObject * @@ -155,16 +157,11 @@ _PyObject_CallOneArg(PyObject *func, PyObject *arg) PyObject *_args[2]; PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET args[0] = arg; - return _PyObject_Vectorcall(func, args, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + PyThreadState *tstate = PyThreadState_GET(); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } -PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( - PyObject *callable, - PyObject *obj, - PyObject *args, - PyObject *kwargs); - PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod( PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h new file mode 100644 index 0000000000000..f7d856a54bd4a --- /dev/null +++ b/Include/internal/pycore_call.h @@ -0,0 +1,39 @@ +#ifndef Py_INTERNAL_CALL_H +#define Py_INTERNAL_CALL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( + PyThreadState *tstate, + PyObject *callable, + PyObject *obj, + PyObject *args, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate( + PyThreadState *tstate, + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_Call( + PyThreadState *tstate, + PyObject *callable, + PyObject *args, + PyObject *kwargs); + +static inline PyObject * +_PyObject_CallNoArgTstate(PyThreadState *tstate, PyObject *func) { + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CALL_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 3c607d08ae745..d08c78df394b3 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1076,6 +1076,7 @@ PYTHON_HEADERS= \ \ $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_atomic.h \ + $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_condvar.h \ diff --git a/Objects/call.c b/Objects/call.c index 96174c4e331e7..ae08d1824468d 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_call.h" #include "pycore_ceval.h" /* _PyEval_EvalFrame() */ #include "pycore_object.h" #include "pycore_pyerrors.h" @@ -18,11 +19,12 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, static PyObject * -null_error(void) +null_error(PyThreadState *tstate) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "null argument to internal routine"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "null argument to internal routine"); + } return NULL; } @@ -81,17 +83,18 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, PyObject * PyObject_CallNoArgs(PyObject *func) { - return _PyObject_CallNoArg(func); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_CallNoArgTstate(tstate, func); } PyObject * -_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwargs) +_PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, + PyObject *const *args, size_t nargsf, + PyObject *kwargs) { assert(callable != NULL); - PyThreadState *tstate = _PyThreadState_GET(); /* _PyObject_FastCallDict() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ @@ -129,11 +132,24 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, } +PyObject * +_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs); +} + + PyObject * _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); + /* Slow path: build a temporary tuple for positional arguments and a * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; @@ -144,9 +160,6 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, return NULL; } - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); PyObject *argstuple = _PyTuple_FromArray(args, nargs); if (argstuple == NULL) { return NULL; @@ -182,8 +195,7 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, Py_DECREF(kwdict); } - result = _Py_CheckFunctionResult(tstate, callable, result, NULL); - return result; + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } @@ -228,14 +240,15 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) PyObject *result = func(callable, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); _PyStack_UnpackDict_Free(args, nargs, kwnames); + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } PyObject * -PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) +_PyObject_Call(PyThreadState *tstate, PyObject *callable, + PyObject *args, PyObject *kwargs) { - PyThreadState *tstate = _PyThreadState_GET(); ternaryfunc call; PyObject *result; @@ -270,11 +283,19 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) } } +PyObject * +PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_Call(tstate, callable, args, kwargs); +} + PyObject * PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) { - return PyObject_Call(callable, args, kwargs); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_Call(tstate, callable, args, kwargs); } @@ -385,30 +406,31 @@ PyObject * PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) { + PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG /* PyEval_CallObjectWithKeywords() must not be called with an exception set. It raises a new exception if parameters are invalid or if PyTuple_New() fails, and so the original exception is lost. */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif if (args != NULL && !PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "argument list must be a tuple"); + _PyErr_SetString(tstate, PyExc_TypeError, + "argument list must be a tuple"); return NULL; } if (kwargs != NULL && !PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, - "keyword list must be a dictionary"); + _PyErr_SetString(tstate, PyExc_TypeError, + "keyword list must be a dictionary"); return NULL; } if (args == NULL) { - return _PyObject_FastCallDict(callable, NULL, 0, kwargs); + return _PyObject_FastCallDictTstate(tstate, callable, NULL, 0, kwargs); } else { - return PyObject_Call(callable, args, kwargs); + return _PyObject_Call(tstate, callable, args, kwargs); } } @@ -416,32 +438,31 @@ PyEval_CallObjectWithKeywords(PyObject *callable, PyObject * PyObject_CallObject(PyObject *callable, PyObject *args) { - assert(!PyErr_Occurred()); + PyThreadState *tstate = _PyThreadState_GET(); + assert(!_PyErr_Occurred(tstate)); if (args == NULL) { - return _PyObject_CallNoArg(callable); + return _PyObject_CallNoArgTstate(tstate, callable); } if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "argument list must be a tuple"); + _PyErr_SetString(tstate, PyExc_TypeError, + "argument list must be a tuple"); return NULL; } - return PyObject_Call(callable, args, NULL); + return _PyObject_Call(tstate, callable, args, NULL); } /* Call callable(obj, *args, **kwargs). */ PyObject * -_PyObject_Call_Prepend(PyObject *callable, +_PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable, PyObject *obj, PyObject *args, PyObject *kwargs) { + assert(PyTuple_Check(args)); + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; - Py_ssize_t argcount; - PyObject *result; - assert(PyTuple_Check(args)); - - argcount = PyTuple_GET_SIZE(args); + Py_ssize_t argcount = PyTuple_GET_SIZE(args); if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; } @@ -459,9 +480,9 @@ _PyObject_Call_Prepend(PyObject *callable, _PyTuple_ITEMS(args), argcount * sizeof(PyObject *)); - result = _PyObject_FastCallDict(callable, - stack, argcount + 1, - kwargs); + PyObject *result = _PyObject_FastCallDictTstate(tstate, callable, + stack, argcount + 1, + kwargs); if (stack != small_stack) { PyMem_Free(stack); } @@ -472,8 +493,8 @@ _PyObject_Call_Prepend(PyObject *callable, /* --- Call with a format string ---------------------------------- */ static PyObject * -_PyObject_CallFunctionVa(PyObject *callable, const char *format, - va_list va, int is_size_t) +_PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, + const char *format, va_list va, int is_size_t) { PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); @@ -482,11 +503,11 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format, PyObject *result; if (callable == NULL) { - return null_error(); + return null_error(tstate); } if (!format || !*format) { - return _PyObject_CallNoArg(callable); + return _PyObject_CallNoArgTstate(tstate, callable); } if (is_size_t) { @@ -507,12 +528,14 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format, - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ PyObject *args = stack[0]; - result = _PyObject_FastCall(callable, - _PyTuple_ITEMS(args), - PyTuple_GET_SIZE(args)); + result = _PyObject_VectorcallTstate(tstate, callable, + _PyTuple_ITEMS(args), + PyTuple_GET_SIZE(args), + NULL); } else { - result = _PyObject_FastCall(callable, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, callable, + stack, nargs, NULL); } for (i = 0; i < nargs; ++i) { @@ -530,9 +553,10 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...) { va_list va; PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); va_end(va); return result; @@ -547,9 +571,10 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...) { va_list va; PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); va_end(va); return result; @@ -559,11 +584,11 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...) PyObject * _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) { - va_list va; - PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); + va_list va; va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 1); + PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1); va_end(va); return result; @@ -571,37 +596,37 @@ _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) static PyObject* -callmethod(PyObject* callable, const char *format, va_list va, int is_size_t) +callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va, int is_size_t) { assert(callable != NULL); - if (!PyCallable_Check(callable)) { - PyErr_Format(PyExc_TypeError, - "attribute of type '%.200s' is not callable", - Py_TYPE(callable)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "attribute of type '%.200s' is not callable", + Py_TYPE(callable)->tp_name); return NULL; } - return _PyObject_CallFunctionVa(callable, format, va, is_size_t); + return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); } PyObject * PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -615,19 +640,19 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) PyObject * PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -639,19 +664,19 @@ PyObject * _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = _PyObject_GetAttrId(obj, name); - if (callable == NULL) + PyObject *callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -663,19 +688,19 @@ PyObject * _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va, 1); va_end(va); Py_DECREF(callable); @@ -687,20 +712,19 @@ PyObject * _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = _PyObject_GetAttrId(obj, name); + PyObject *callable = _PyObject_GetAttrId(obj, name); if (callable == NULL) { return NULL; } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va, 1); va_end(va); Py_DECREF(callable); @@ -711,7 +735,8 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, /* --- Call with "..." arguments ---------------------------------- */ static PyObject * -object_vacall(PyObject *base, PyObject *callable, va_list vargs) +object_vacall(PyThreadState *tstate, PyObject *base, + PyObject *callable, va_list vargs) { PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; @@ -721,7 +746,7 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) va_list countva; if (callable == NULL) { - return null_error(); + return null_error(tstate); } /* Count the number of arguments */ @@ -758,7 +783,7 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) } /* Call the function */ - result = _PyObject_FastCall(callable, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); if (stack != small_stack) { PyMem_Free(stack); @@ -804,8 +829,9 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, PyObject * PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) { + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } PyObject *callable = NULL; @@ -817,7 +843,7 @@ PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) va_list vargs; va_start(vargs, name); - PyObject *result = object_vacall(obj, callable, vargs); + PyObject *result = object_vacall(tstate, obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -829,8 +855,9 @@ PyObject * _PyObject_CallMethodIdObjArgs(PyObject *obj, struct _Py_Identifier *name, ...) { + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ @@ -847,7 +874,7 @@ _PyObject_CallMethodIdObjArgs(PyObject *obj, va_list vargs; va_start(vargs, name); - PyObject *result = object_vacall(obj, callable, vargs); + PyObject *result = object_vacall(tstate, obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -858,11 +885,12 @@ _PyObject_CallMethodIdObjArgs(PyObject *obj, PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...) { + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; PyObject *result; va_start(vargs, callable); - result = object_vacall(NULL, callable, vargs); + result = object_vacall(tstate, NULL, callable, vargs); va_end(vargs); return result; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 50a3c15785a90..720363410ceb1 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1,6 +1,7 @@ /* Type object implementation */ #include "Python.h" +#include "pycore_call.h" #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" @@ -6554,19 +6555,21 @@ slot_tp_hash(PyObject *self) static PyObject * slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); _Py_IDENTIFIER(__call__); int unbound; - PyObject *meth = lookup_method(self, &PyId___call__, &unbound); - PyObject *res; - if (meth == NULL) + PyObject *meth = lookup_method(self, &PyId___call__, &unbound); + if (meth == NULL) { return NULL; + } + PyObject *res; if (unbound) { - res = _PyObject_Call_Prepend(meth, self, args, kwds); + res = _PyObject_Call_Prepend(tstate, meth, self, args, kwds); } else { - res = PyObject_Call(meth, args, kwds); + res = _PyObject_Call(tstate, meth, args, kwds); } Py_DECREF(meth); @@ -6688,17 +6691,16 @@ static PyObject * slot_tp_richcompare(PyObject *self, PyObject *other, int op) { PyThreadState *tstate = _PyThreadState_GET(); - int unbound; - PyObject *func, *res; - func = lookup_maybe_method(self, &name_op[op], &unbound); + int unbound; + PyObject *func = lookup_maybe_method(self, &name_op[op], &unbound); if (func == NULL) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } PyObject *stack[2] = {self, other}; - res = vectorcall_unbound(tstate, unbound, func, stack, 2); + PyObject *res = vectorcall_unbound(tstate, unbound, func, stack, 2); Py_DECREF(func); return res; } @@ -6793,18 +6795,21 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) static int slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); + _Py_IDENTIFIER(__init__); int unbound; PyObject *meth = lookup_method(self, &PyId___init__, &unbound); - PyObject *res; - - if (meth == NULL) + if (meth == NULL) { return -1; + } + + PyObject *res; if (unbound) { - res = _PyObject_Call_Prepend(meth, self, args, kwds); + res = _PyObject_Call_Prepend(tstate, meth, self, args, kwds); } else { - res = PyObject_Call(meth, args, kwds); + res = _PyObject_Call(tstate, meth, args, kwds); } Py_DECREF(meth); if (res == NULL) @@ -6823,6 +6828,7 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *func, *result; func = _PyObject_GetAttrId((PyObject *)type, &PyId___new__); @@ -6830,7 +6836,7 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - result = _PyObject_Call_Prepend(func, (PyObject *)type, args, kwds); + result = _PyObject_Call_Prepend(tstate, func, (PyObject *)type, args, kwds); Py_DECREF(func); return result; } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index b72474060a362..f5be8aa4051e8 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -160,6 +160,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 80908135550b6..ba1839f8a3814 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -183,6 +183,9 @@ Include + + Include + Include diff --git a/Python/_warnings.c b/Python/_warnings.c index dd2b072d41685..b8585d204787d 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "frameobject.h" #include "clinic/_warnings.c.h" @@ -27,10 +28,11 @@ static struct PyModuleDef warningsmodule; static WarningsState * _Warnings_GetState() { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); if (tstate == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "_Warnings_GetState: could not identify current interpreter"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "_Warnings_GetState: could not identify " + "current interpreter"); return NULL; } return &tstate->interp->warnings; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d79e254cc68ca..4470310a84e73 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -4,6 +4,7 @@ #include #include "ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" @@ -1254,23 +1255,23 @@ map_next(mapobject *lz) { PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; - Py_ssize_t niters, nargs, i; PyObject *result = NULL; + PyThreadState *tstate = _PyThreadState_GET(); - niters = PyTuple_GET_SIZE(lz->iters); + const Py_ssize_t niters = PyTuple_GET_SIZE(lz->iters); if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; } else { stack = PyMem_Malloc(niters * sizeof(stack[0])); if (stack == NULL) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } } - nargs = 0; - for (i=0; i < niters; i++) { + Py_ssize_t nargs = 0; + for (Py_ssize_t i=0; i < niters; i++) { PyObject *it = PyTuple_GET_ITEM(lz->iters, i); PyObject *val = Py_TYPE(it)->tp_iternext(it); if (val == NULL) { @@ -1280,10 +1281,10 @@ map_next(mapobject *lz) nargs++; } - result = _PyObject_FastCall(lz->func, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL); exit: - for (i=0; i < nargs; i++) { + for (Py_ssize_t i=0; i < nargs; i++) { Py_DECREF(stack[i]); } if (stack != small_stack) { diff --git a/Python/ceval.c b/Python/ceval.c index 046cd69151b4e..11d25a53d527a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -10,6 +10,7 @@ #define PY_LOCAL_AGGRESSIVE #include "Python.h" +#include "pycore_call.h" #include "pycore_ceval.h" #include "pycore_code.h" #include "pycore_object.h" @@ -4306,7 +4307,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, current Python frame (f), the associated C stack is still in use, so recursion_depth must be boosted for the duration. */ - assert(tstate != NULL); if (Py_REFCNT(f) > 1) { Py_DECREF(f); _PyObject_GC_TRACK(f); @@ -5024,10 +5024,11 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject return NULL; } - C_TRACE(result, _PyObject_FastCallDict(func, - &_PyTuple_ITEMS(callargs)[1], - nargs - 1, - kwdict)); + C_TRACE(result, _PyObject_FastCallDictTstate( + tstate, func, + &_PyTuple_ITEMS(callargs)[1], + nargs - 1, + kwdict)); Py_DECREF(func); return result; } From webhook-mailer at python.org Thu Nov 14 21:48:09 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 02:48:09 -0000 Subject: [Python-checkins] bpo-38692: Add asyncio.PidfdChildWatcher to __all__ (GH-17161) Message-ID: https://github.com/python/cpython/commit/3f8cebd32c1e6f20a1a1440e51c308a5f70ca959 commit: 3f8cebd32c1e6f20a1a1440e51c308a5f70ca959 branch: master author: Kyle Stanley committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-14T18:47:56-08:00 summary: bpo-38692: Add asyncio.PidfdChildWatcher to __all__ (GH-17161) /cc @asvetlov @1st1 https://bugs.python.org/issue38692 Automerge-Triggered-By: @benjaminp files: M Lib/asyncio/unix_events.py diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index d02460c004376..66213728a3dcb 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -29,7 +29,7 @@ __all__ = ( 'SelectorEventLoop', 'AbstractChildWatcher', 'SafeChildWatcher', - 'FastChildWatcher', + 'FastChildWatcher', 'PidfdChildWatcher', 'MultiLoopChildWatcher', 'ThreadedChildWatcher', 'DefaultEventLoopPolicy', ) From webhook-mailer at python.org Fri Nov 15 03:22:52 2019 From: webhook-mailer at python.org (Tal Einat) Date: Fri, 15 Nov 2019 08:22:52 -0000 Subject: [Python-checkins] Add .pytest_cache to .gitignore (GH-16595) Message-ID: https://github.com/python/cpython/commit/57d3ab85a4a4cf740b538ca3450849986f85df87 commit: 57d3ab85a4a4cf740b538ca3450849986f85df87 branch: master author: Brandt Bucher committer: Tal Einat date: 2019-11-15T10:22:41+02:00 summary: Add .pytest_cache to .gitignore (GH-16595) files: M .gitignore diff --git a/.gitignore b/.gitignore index 0e3f973d0fc7c..b11f72f69fae5 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ TAGS gmon.out .coverage .mypy_cache/ +.pytest_cache/ *.exe !Lib/distutils/command/*.exe From webhook-mailer at python.org Fri Nov 15 03:43:35 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Fri, 15 Nov 2019 08:43:35 -0000 Subject: [Python-checkins] bpo-38677: Fix arraymodule error handling in module initialization. (GH-17039) Message-ID: https://github.com/python/cpython/commit/b44ffc8b409fd539c5fb2b79385498e9fe168880 commit: b44ffc8b409fd539c5fb2b79385498e9fe168880 branch: master author: Marco Paolini committer: Serhiy Storchaka date: 2019-11-15T10:42:51+02:00 summary: bpo-38677: Fix arraymodule error handling in module initialization. (GH-17039) files: M Modules/arraymodule.c diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 5ba261819db2c..1ceba9e63cbdf 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -3040,9 +3040,15 @@ array_modexec(PyObject *m) Py_TYPE(&PyArrayIter_Type) = &PyType_Type; Py_INCREF((PyObject *)&Arraytype); - PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype); + if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } Py_INCREF((PyObject *)&Arraytype); - PyModule_AddObject(m, "array", (PyObject *)&Arraytype); + if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } for (descr=descriptors; descr->typecode != '\0'; descr++) { size++; @@ -3053,13 +3059,11 @@ array_modexec(PyObject *m) *p++ = (char)descr->typecode; } typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL); - - PyModule_AddObject(m, "typecodes", typecodes); - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; + if (PyModule_AddObject(m, "typecodes", typecodes) < 0) { + Py_XDECREF(typecodes); + return -1; } + return 0; } From webhook-mailer at python.org Fri Nov 15 04:03:51 2019 From: webhook-mailer at python.org (Tal Einat) Date: Fri, 15 Nov 2019 09:03:51 -0000 Subject: [Python-checkins] bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) Message-ID: https://github.com/python/cpython/commit/e8acc865a3f112b98417f676c897ca6ec2dac2c7 commit: e8acc865a3f112b98417f676c897ca6ec2dac2c7 branch: master author: Andrey Doroschenko committer: Tal Einat date: 2019-11-15T11:03:46+02:00 summary: bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) files: A Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst M Doc/includes/email-dir.py M Doc/includes/email-simple.py M Doc/includes/email-unpack.py diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py index 0dcfbfb4025c8..2fc1570e654db 100644 --- a/Doc/includes/email-dir.py +++ b/Doc/includes/email-dir.py @@ -41,7 +41,7 @@ def main(): directory = '.' # Create the message msg = EmailMessage() - msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory) + msg['Subject'] = f'Contents of directory {os.path.abspath(directory)}' msg['To'] = ', '.join(args.recipients) msg['From'] = args.sender msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py index f69ef40ff04c9..07dc30fd066ea 100644 --- a/Doc/includes/email-simple.py +++ b/Doc/includes/email-simple.py @@ -12,7 +12,7 @@ # me == the sender's email address # you == the recipient's email address -msg['Subject'] = 'The contents of %s' % textfile +msg['Subject'] = f'The contents of {textfile}' msg['From'] = me msg['To'] = you diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py index e0a7f01f58bb5..c8cb0be456083 100644 --- a/Doc/includes/email-unpack.py +++ b/Doc/includes/email-unpack.py @@ -43,7 +43,7 @@ def main(): if not ext: # Use a generic bag-of-bits extension ext = '.bin' - filename = 'part-%03d%s' % (counter, ext) + filename = f'part-{counter:03d}{ext}' counter += 1 with open(os.path.join(args.directory, filename), 'wb') as fp: fp.write(part.get_payload(decode=True)) diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst new file mode 100644 index 0000000000000..8e0dc9eb4ca2f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst @@ -0,0 +1 @@ +Modernize :mod:`email` examples from %-formatting to f-strings. \ No newline at end of file From webhook-mailer at python.org Fri Nov 15 04:11:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 09:11:52 -0000 Subject: [Python-checkins] bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) Message-ID: https://github.com/python/cpython/commit/dae27cc8e72106c2eceeff9af83d1e58b2bb68d5 commit: dae27cc8e72106c2eceeff9af83d1e58b2bb68d5 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T01:11:48-08:00 summary: bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) (cherry picked from commit e8acc865a3f112b98417f676c897ca6ec2dac2c7) Co-authored-by: Andrey Doroschenko files: A Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst M Doc/includes/email-dir.py M Doc/includes/email-simple.py M Doc/includes/email-unpack.py diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py index 0dcfbfb4025c8..2fc1570e654db 100644 --- a/Doc/includes/email-dir.py +++ b/Doc/includes/email-dir.py @@ -41,7 +41,7 @@ def main(): directory = '.' # Create the message msg = EmailMessage() - msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory) + msg['Subject'] = f'Contents of directory {os.path.abspath(directory)}' msg['To'] = ', '.join(args.recipients) msg['From'] = args.sender msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py index f69ef40ff04c9..07dc30fd066ea 100644 --- a/Doc/includes/email-simple.py +++ b/Doc/includes/email-simple.py @@ -12,7 +12,7 @@ # me == the sender's email address # you == the recipient's email address -msg['Subject'] = 'The contents of %s' % textfile +msg['Subject'] = f'The contents of {textfile}' msg['From'] = me msg['To'] = you diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py index e0a7f01f58bb5..c8cb0be456083 100644 --- a/Doc/includes/email-unpack.py +++ b/Doc/includes/email-unpack.py @@ -43,7 +43,7 @@ def main(): if not ext: # Use a generic bag-of-bits extension ext = '.bin' - filename = 'part-%03d%s' % (counter, ext) + filename = f'part-{counter:03d}{ext}' counter += 1 with open(os.path.join(args.directory, filename), 'wb') as fp: fp.write(part.get_payload(decode=True)) diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst new file mode 100644 index 0000000000000..8e0dc9eb4ca2f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst @@ -0,0 +1 @@ +Modernize :mod:`email` examples from %-formatting to f-strings. \ No newline at end of file From webhook-mailer at python.org Fri Nov 15 04:14:50 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 09:14:50 -0000 Subject: [Python-checkins] bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) Message-ID: https://github.com/python/cpython/commit/fe67a5354010f33128c4f461da8ffb925e0f4de8 commit: fe67a5354010f33128c4f461da8ffb925e0f4de8 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T01:14:44-08:00 summary: bpo-38351: Modernize email examples from %-formatting to f-strings (GH-17162) (cherry picked from commit e8acc865a3f112b98417f676c897ca6ec2dac2c7) Co-authored-by: Andrey Doroschenko files: A Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst M Doc/includes/email-dir.py M Doc/includes/email-simple.py M Doc/includes/email-unpack.py diff --git a/Doc/includes/email-dir.py b/Doc/includes/email-dir.py index 0dcfbfb4025c8..2fc1570e654db 100644 --- a/Doc/includes/email-dir.py +++ b/Doc/includes/email-dir.py @@ -41,7 +41,7 @@ def main(): directory = '.' # Create the message msg = EmailMessage() - msg['Subject'] = 'Contents of directory %s' % os.path.abspath(directory) + msg['Subject'] = f'Contents of directory {os.path.abspath(directory)}' msg['To'] = ', '.join(args.recipients) msg['From'] = args.sender msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py index f69ef40ff04c9..07dc30fd066ea 100644 --- a/Doc/includes/email-simple.py +++ b/Doc/includes/email-simple.py @@ -12,7 +12,7 @@ # me == the sender's email address # you == the recipient's email address -msg['Subject'] = 'The contents of %s' % textfile +msg['Subject'] = f'The contents of {textfile}' msg['From'] = me msg['To'] = you diff --git a/Doc/includes/email-unpack.py b/Doc/includes/email-unpack.py index e0a7f01f58bb5..c8cb0be456083 100644 --- a/Doc/includes/email-unpack.py +++ b/Doc/includes/email-unpack.py @@ -43,7 +43,7 @@ def main(): if not ext: # Use a generic bag-of-bits extension ext = '.bin' - filename = 'part-%03d%s' % (counter, ext) + filename = f'part-{counter:03d}{ext}' counter += 1 with open(os.path.join(args.directory, filename), 'wb') as fp: fp.write(part.get_payload(decode=True)) diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst new file mode 100644 index 0000000000000..8e0dc9eb4ca2f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst @@ -0,0 +1 @@ +Modernize :mod:`email` examples from %-formatting to f-strings. \ No newline at end of file From webhook-mailer at python.org Fri Nov 15 04:37:33 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 09:37:33 -0000 Subject: [Python-checkins] bpo-38677: Fix arraymodule error handling in module initialization. (GH-17039) Message-ID: https://github.com/python/cpython/commit/25ce77dd2455abbb6e2c9e055bbc98954642fa7c commit: 25ce77dd2455abbb6e2c9e055bbc98954642fa7c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T01:37:26-08:00 summary: bpo-38677: Fix arraymodule error handling in module initialization. (GH-17039) (cherry picked from commit b44ffc8b409fd539c5fb2b79385498e9fe168880) Co-authored-by: Marco Paolini files: M Modules/arraymodule.c diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 26c90a8a5983d..5289ea0e91a61 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -3042,9 +3042,15 @@ array_modexec(PyObject *m) Py_TYPE(&PyArrayIter_Type) = &PyType_Type; Py_INCREF((PyObject *)&Arraytype); - PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype); + if (PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } Py_INCREF((PyObject *)&Arraytype); - PyModule_AddObject(m, "array", (PyObject *)&Arraytype); + if (PyModule_AddObject(m, "array", (PyObject *)&Arraytype) < 0) { + Py_DECREF((PyObject *)&Arraytype); + return -1; + } for (descr=descriptors; descr->typecode != '\0'; descr++) { size++; @@ -3055,13 +3061,11 @@ array_modexec(PyObject *m) *p++ = (char)descr->typecode; } typecodes = PyUnicode_DecodeASCII(buffer, p - buffer, NULL); - - PyModule_AddObject(m, "typecodes", typecodes); - - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; + if (PyModule_AddObject(m, "typecodes", typecodes) < 0) { + Py_XDECREF(typecodes); + return -1; } + return 0; } From webhook-mailer at python.org Fri Nov 15 11:56:13 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 16:56:13 -0000 Subject: [Python-checkins] bpo-38778: Document that os.fork is not allowed in subinterpreters (GH-17123) Message-ID: https://github.com/python/cpython/commit/b22030073b9327a3aeccb69507694bce078192aa commit: b22030073b9327a3aeccb69507694bce078192aa branch: master author: Phil Connell committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-15T08:56:03-08:00 summary: bpo-38778: Document that os.fork is not allowed in subinterpreters (GH-17123) Small docs update for [bpo-34651](https://bugs.python.org/issue34651). Other references to fork (e.g. the PyOS.*Fork functions or discussions of fork() when embedding Python) point back to os.fork, so I don't think any other updates are needed. https://bugs.python.org/issue38778 Automerge-Triggered-By: @ericsnowcurrently files: A Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 652d8de4e384f..4fec647828e25 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3478,7 +3478,11 @@ written in Python, such as a mail server's external command delivery program. parent. If an error occurs :exc:`OSError` is raised. Note that some platforms including FreeBSD <= 6.3 and Cygwin have - known issues when using fork() from a thread. + known issues when using ``fork()`` from a thread. + + .. versionchanged:: 3.8 + Calling ``fork()`` in a subinterpreter is no longer supported + (:exc:`RuntimeError` is raised). .. warning:: @@ -3495,6 +3499,10 @@ written in Python, such as a mail server's external command delivery program. master end of the pseudo-terminal. For a more portable approach, use the :mod:`pty` module. If an error occurs :exc:`OSError` is raised. + .. versionchanged:: 3.8 + Calling ``forkpty()`` in a subinterpreter is no longer supported + (:exc:`RuntimeError` is raised). + .. availability:: some flavors of Unix. diff --git a/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst b/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst new file mode 100644 index 0000000000000..053e1d294b70f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst @@ -0,0 +1 @@ +Document the fact that :exc:`RuntimeError` is raised if :meth:`os.fork` is called in a subinterpreter. From webhook-mailer at python.org Fri Nov 15 12:49:28 2019 From: webhook-mailer at python.org (Steve Dower) Date: Fri, 15 Nov 2019 17:49:28 -0000 Subject: [Python-checkins] bpo-38453: Ensure ntpath.realpath correctly resolves relative paths (GH-16967) Message-ID: https://github.com/python/cpython/commit/abde52cd8e31830bfc06c5803221faae6172104a commit: abde52cd8e31830bfc06c5803221faae6172104a branch: master author: Steve Dower committer: GitHub date: 2019-11-15T09:49:21-08:00 summary: bpo-38453: Ensure ntpath.realpath correctly resolves relative paths (GH-16967) Ensure isabs() is always True for \\?\ prefixed paths Avoid unnecessary usage of readlink() to avoid resolving broken links incorrectly Ensure shutil tests run in test directory files: A Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst M Lib/ntpath.py M Lib/test/test_ntpath.py M Lib/test/test_shutil.py diff --git a/Lib/ntpath.py b/Lib/ntpath.py index d4ecff97c9528..6f771773a7d1b 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -61,6 +61,14 @@ def normcase(s): def isabs(s): """Test whether a path is absolute""" s = os.fspath(s) + # Paths beginning with \\?\ are always absolute, but do not + # necessarily contain a drive. + if isinstance(s, bytes): + if s.replace(b'/', b'\\').startswith(b'\\\\?\\'): + return True + else: + if s.replace('/', '\\').startswith('\\\\?\\'): + return True s = splitdrive(s)[1] return len(s) > 0 and s[0] in _get_bothseps(s) @@ -526,10 +534,7 @@ def abspath(path): # realpath is a no-op on systems without _getfinalpathname support. realpath = abspath else: - def _readlink_deep(path, seen=None): - if seen is None: - seen = set() - + def _readlink_deep(path): # These error codes indicate that we should stop reading links and # return the path we currently have. # 1: ERROR_INVALID_FUNCTION @@ -546,10 +551,22 @@ def _readlink_deep(path, seen=None): # 4393: ERROR_REPARSE_TAG_INVALID allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393 + seen = set() while normcase(path) not in seen: seen.add(normcase(path)) try: + old_path = path path = _nt_readlink(path) + # Links may be relative, so resolve them against their + # own location + if not isabs(path): + # If it's something other than a symlink, we don't know + # what it's actually going to be resolved against, so + # just return the old path. + if not islink(old_path): + path = old_path + break + path = normpath(join(dirname(old_path), path)) except OSError as ex: if ex.winerror in allowed_winerror: break @@ -579,23 +596,31 @@ def _getfinalpathname_nonstrict(path): # Non-strict algorithm is to find as much of the target directory # as we can and join the rest. tail = '' - seen = set() while path: try: - path = _readlink_deep(path, seen) path = _getfinalpathname(path) return join(path, tail) if tail else path except OSError as ex: if ex.winerror not in allowed_winerror: raise + try: + # The OS could not resolve this path fully, so we attempt + # to follow the link ourselves. If we succeed, join the tail + # and return. + new_path = _readlink_deep(path) + if new_path != path: + return join(new_path, tail) if tail else new_path + except OSError: + # If we fail to readlink(), let's keep traversing + pass path, name = split(path) # TODO (bpo-38186): Request the real file name from the directory # entry using FindFirstFileW. For now, we will return the path # as best we have it if path and not name: - return abspath(path + tail) + return path + tail tail = join(name, tail) if tail else name - return abspath(tail) + return tail def realpath(path): path = normpath(path) @@ -604,12 +629,20 @@ def realpath(path): unc_prefix = b'\\\\?\\UNC\\' new_unc_prefix = b'\\\\' cwd = os.getcwdb() + # bpo-38081: Special case for realpath(b'nul') + if normcase(path) == normcase(os.fsencode(devnull)): + return b'\\\\.\\NUL' else: prefix = '\\\\?\\' unc_prefix = '\\\\?\\UNC\\' new_unc_prefix = '\\\\' cwd = os.getcwd() + # bpo-38081: Special case for realpath('nul') + if normcase(path) == normcase(devnull): + return '\\\\.\\NUL' had_prefix = path.startswith(prefix) + if not had_prefix and not isabs(path): + path = join(cwd, path) try: path = _getfinalpathname(path) initial_winerror = 0 diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index e0ec441985230..a84b94c9badbe 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -286,14 +286,16 @@ def test_realpath_broken_symlinks(self): ABSTFN + r"\missing") self.assertPathEqual(ntpath.realpath(r"broken\foo"), ABSTFN + r"\missing\foo") + # bpo-38453: We no longer recursively resolve segments of relative + # symlinks that the OS cannot resolve. self.assertPathEqual(ntpath.realpath(r"broken1"), - ABSTFN + r"\missing\bar") + ABSTFN + r"\broken\bar") self.assertPathEqual(ntpath.realpath(r"broken1\baz"), - ABSTFN + r"\missing\bar\baz") + ABSTFN + r"\broken\bar\baz") self.assertPathEqual(ntpath.realpath("broken2"), - ABSTFN + r"\missing") + ABSTFN + r"\self\self\missing") self.assertPathEqual(ntpath.realpath("broken3"), - ABSTFN + r"\missing") + ABSTFN + r"\subdir\parent\subdir\parent\missing") self.assertPathEqual(ntpath.realpath("broken4"), ABSTFN + r"\missing") self.assertPathEqual(ntpath.realpath("broken5"), @@ -304,13 +306,13 @@ def test_realpath_broken_symlinks(self): self.assertPathEqual(ntpath.realpath(rb"broken\foo"), os.fsencode(ABSTFN + r"\missing\foo")) self.assertPathEqual(ntpath.realpath(rb"broken1"), - os.fsencode(ABSTFN + r"\missing\bar")) + os.fsencode(ABSTFN + r"\broken\bar")) self.assertPathEqual(ntpath.realpath(rb"broken1\baz"), - os.fsencode(ABSTFN + r"\missing\bar\baz")) + os.fsencode(ABSTFN + r"\broken\bar\baz")) self.assertPathEqual(ntpath.realpath(b"broken2"), - os.fsencode(ABSTFN + r"\missing")) + os.fsencode(ABSTFN + r"\self\self\missing")) self.assertPathEqual(ntpath.realpath(rb"broken3"), - os.fsencode(ABSTFN + r"\missing")) + os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing")) self.assertPathEqual(ntpath.realpath(b"broken4"), os.fsencode(ABSTFN + r"\missing")) self.assertPathEqual(ntpath.realpath(b"broken5"), @@ -319,8 +321,8 @@ def test_realpath_broken_symlinks(self): @support.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_loops(self): - # Bug #930024, return the path unchanged if we get into an infinite - # symlink loop. + # Symlink loops are non-deterministic as to which path is returned, but + # it will always be the fully resolved path of one member of the cycle ABSTFN = ntpath.abspath(support.TESTFN) self.addCleanup(support.unlink, ABSTFN) self.addCleanup(support.unlink, ABSTFN + "1") @@ -332,8 +334,6 @@ def test_realpath_symlink_loops(self): os.symlink(ABSTFN, ABSTFN) self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN) - # cycles are non-deterministic as to which path is returned, but - # it will always be the fully resolved path of one member of the cycle os.symlink(ABSTFN + "1", ABSTFN + "2") os.symlink(ABSTFN + "2", ABSTFN + "1") expected = (ABSTFN + "1", ABSTFN + "2") @@ -402,6 +402,34 @@ def test_realpath_symlink_prefix(self): def test_realpath_nul(self): tester("ntpath.realpath('NUL')", r'\\.\NUL') + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_cwd(self): + ABSTFN = ntpath.abspath(support.TESTFN) + + support.unlink(ABSTFN) + support.rmtree(ABSTFN) + os.mkdir(ABSTFN) + self.addCleanup(support.rmtree, ABSTFN) + + test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") + test_dir_short = ntpath.join(ABSTFN, "MYVERY~1") + test_file_long = ntpath.join(test_dir_long, "file.txt") + test_file_short = ntpath.join(test_dir_short, "file.txt") + + os.mkdir(test_dir_long) + + with open(test_file_long, "wb") as f: + f.write(b"content") + + self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) + + with support.change_cwd(test_dir_long): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + with support.change_cwd(test_dir_long.lower()): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + with support.change_cwd(test_dir_short): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + def test_expandvars(self): with support.EnvironmentVarGuard() as env: env.clear() diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 428d4f341715c..dd5589b2e3a5c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -123,12 +123,12 @@ def supports_file2file_sendfile(): srcname = None dstname = None try: - with tempfile.NamedTemporaryFile("wb", delete=False) as f: + with tempfile.NamedTemporaryFile("wb", dir=os.getcwd(), delete=False) as f: srcname = f.name f.write(b"0123456789") with open(srcname, "rb") as src: - with tempfile.NamedTemporaryFile("wb", delete=False) as dst: + with tempfile.NamedTemporaryFile("wb", dir=os.getcwd(), delete=False) as dst: dstname = dst.name infd = src.fileno() outfd = dst.fileno() @@ -162,12 +162,12 @@ def _maxdataOK(): class BaseTest: - def mkdtemp(self): + def mkdtemp(self, prefix=None): """Create a temporary directory that will be cleaned up. Returns the path of the directory. """ - d = tempfile.mkdtemp() + d = tempfile.mkdtemp(prefix=prefix, dir=os.getcwd()) self.addCleanup(support.rmtree, d) return d @@ -231,6 +231,7 @@ def test_rmtree_fails_on_junctions(self): os.mkdir(dir_) link = os.path.join(tmp, 'link') _winapi.CreateJunction(dir_, link) + self.addCleanup(support.unlink, link) self.assertRaises(OSError, shutil.rmtree, link) self.assertTrue(os.path.exists(dir_)) self.assertTrue(os.path.lexists(link)) @@ -267,7 +268,7 @@ def test_rmtree_works_on_junctions(self): def test_rmtree_errors(self): # filename is guaranteed not to exist - filename = tempfile.mktemp() + filename = tempfile.mktemp(dir=self.mkdtemp()) self.assertRaises(FileNotFoundError, shutil.rmtree, filename) # test that ignore_errors option is honored shutil.rmtree(filename, ignore_errors=True) @@ -401,7 +402,7 @@ def _raiser(*args, **kwargs): def test_rmtree_dont_delete_file(self): # When called on a file instead of a directory, don't delete it. - handle, path = tempfile.mkstemp() + handle, path = tempfile.mkstemp(dir=self.mkdtemp()) os.close(handle) self.assertRaises(NotADirectoryError, shutil.rmtree, path) os.remove(path) @@ -438,8 +439,8 @@ def test_rmtree_on_junction(self): class TestCopyTree(BaseTest, unittest.TestCase): def test_copytree_simple(self): - src_dir = tempfile.mkdtemp() - dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') + src_dir = self.mkdtemp() + dst_dir = os.path.join(self.mkdtemp(), 'destination') self.addCleanup(shutil.rmtree, src_dir) self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir)) write_file((src_dir, 'test.txt'), '123') @@ -457,8 +458,8 @@ def test_copytree_simple(self): self.assertEqual(actual, '456') def test_copytree_dirs_exist_ok(self): - src_dir = tempfile.mkdtemp() - dst_dir = tempfile.mkdtemp() + src_dir = self.mkdtemp() + dst_dir = self.mkdtemp() self.addCleanup(shutil.rmtree, src_dir) self.addCleanup(shutil.rmtree, dst_dir) @@ -517,9 +518,9 @@ def test_copytree_with_exclude(self): # creating data join = os.path.join exists = os.path.exists - src_dir = tempfile.mkdtemp() + src_dir = self.mkdtemp() try: - dst_dir = join(tempfile.mkdtemp(), 'destination') + dst_dir = join(self.mkdtemp(), 'destination') write_file((src_dir, 'test.txt'), '123') write_file((src_dir, 'test.tmp'), '123') os.mkdir(join(src_dir, 'test_dir')) @@ -579,7 +580,7 @@ def _filter(src, names): shutil.rmtree(os.path.dirname(dst_dir)) def test_copytree_retains_permissions(self): - tmp_dir = tempfile.mkdtemp() + tmp_dir = self.mkdtemp() src_dir = os.path.join(tmp_dir, 'source') os.mkdir(src_dir) dst_dir = os.path.join(tmp_dir, 'destination') @@ -591,6 +592,7 @@ def test_copytree_retains_permissions(self): write_file((src_dir, 'restrictive.txt'), '456') os.chmod(os.path.join(src_dir, 'restrictive.txt'), 0o600) restrictive_subdir = tempfile.mkdtemp(dir=src_dir) + self.addCleanup(support.rmtree, restrictive_subdir) os.chmod(restrictive_subdir, 0o600) shutil.copytree(src_dir, dst_dir) @@ -609,8 +611,8 @@ def test_copytree_winerror(self, mock_patch): # When copying to VFAT, copystat() raises OSError. On Windows, the # exception object has a meaningful 'winerror' attribute, but not # on other operating systems. Do not assume 'winerror' is set. - src_dir = tempfile.mkdtemp() - dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') + src_dir = self.mkdtemp() + dst_dir = os.path.join(self.mkdtemp(), 'destination') self.addCleanup(shutil.rmtree, src_dir) self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir)) @@ -628,10 +630,8 @@ def custom_cpfun(a, b): self.assertEqual(b, os.path.join(dst, 'foo')) flag = [] - src = tempfile.mkdtemp() - self.addCleanup(support.rmtree, src) - dst = tempfile.mktemp() - self.addCleanup(support.rmtree, dst) + src = self.mkdtemp() + dst = tempfile.mktemp(dir=self.mkdtemp()) with open(os.path.join(src, 'foo'), 'w') as f: f.close() shutil.copytree(src, dst, copy_function=custom_cpfun) @@ -1624,8 +1624,7 @@ def check_chown(path, uid=None, gid=None): class TestWhich(BaseTest, unittest.TestCase): def setUp(self): - self.temp_dir = tempfile.mkdtemp(prefix="Tmp") - self.addCleanup(support.rmtree, self.temp_dir) + self.temp_dir = self.mkdtemp(prefix="Tmp") # Give the temp_file an ".exe" suffix for all. # It's needed on Windows and not harmful on other platforms. self.temp_file = tempfile.NamedTemporaryFile(dir=self.temp_dir, @@ -1857,7 +1856,7 @@ def test_move_file_to_dir_other_fs(self): def test_move_dir(self): # Move a dir to another location on the same filesystem. - dst_dir = tempfile.mktemp() + dst_dir = tempfile.mktemp(dir=self.mkdtemp()) try: self._check_move_dir(self.src_dir, dst_dir, dst_dir) finally: @@ -2156,7 +2155,7 @@ def test_win_impl(self): # If file size < 1 MiB memoryview() length must be equal to # the actual file size. - with tempfile.NamedTemporaryFile(delete=False) as f: + with tempfile.NamedTemporaryFile(dir=os.getcwd(), delete=False) as f: f.write(b'foo') fname = f.name self.addCleanup(support.unlink, fname) @@ -2165,7 +2164,7 @@ def test_win_impl(self): self.assertEqual(m.call_args[0][2], 3) # Empty files should not rely on readinto() variant. - with tempfile.NamedTemporaryFile(delete=False) as f: + with tempfile.NamedTemporaryFile(dir=os.getcwd(), delete=False) as f: pass fname = f.name self.addCleanup(support.unlink, fname) @@ -2231,7 +2230,7 @@ def test_same_file(self): self.assertEqual(read_file(TESTFN, binary=True), self.FILEDATA) def test_non_existent_src(self): - name = tempfile.mktemp() + name = tempfile.mktemp(dir=os.getcwd()) with self.assertRaises(FileNotFoundError) as cm: shutil.copyfile(name, "new") self.assertEqual(cm.exception.filename, name) diff --git a/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst b/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst new file mode 100644 index 0000000000000..deacb03c6f01d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst @@ -0,0 +1 @@ +Ensure ntpath.realpath() correctly resolves relative paths. From webhook-mailer at python.org Fri Nov 15 16:29:07 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 21:29:07 -0000 Subject: [Python-checkins] bpo-38816: Add notes in the C-API docs about fork in subinterpreters. (GH-17176) Message-ID: https://github.com/python/cpython/commit/73cdb0c6b2c3861e034004cdc57be5e726876078 commit: 73cdb0c6b2c3861e034004cdc57be5e726876078 branch: master author: Eric Snow committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-15T13:28:54-08:00 summary: bpo-38816: Add notes in the C-API docs about fork in subinterpreters. (GH-17176) The C-API docs are a bit sparse on the interplay between C `fork()` and the CPython runtime. This change adds some more information on the subject. https://bugs.python.org/issue38816 files: A Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst M Doc/c-api/init.rst M Doc/c-api/sys.rst diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index dc30e49682551..86bf7f9eec65e 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -769,9 +769,19 @@ supports the creation of additional interpreters (using :c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the :c:func:`PyGILState_\*` API is unsupported. + +.. _fork-and-threads: + +Cautions about fork() +--------------------- + Another important thing to note about threads is their behaviour in the face of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a -process forks only the thread that issued the fork will exist. That also +process forks only the thread that issued the fork will exist. This has a +concrete impact both on how locks must be handled and on all stored state +in CPython's runtime. + +The fact that only the "current" thread remains means any locks held by other threads will never be released. Python solves this for :func:`os.fork` by acquiring the locks it uses internally before the fork, and releasing them afterwards. In addition, it resets any @@ -786,6 +796,17 @@ being held by a thread that is defunct after the fork. :c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not always able to. +The fact that all other threads go away also means that CPython's +runtime state there must be cleaned up properly, which :func:`os.fork` +does. This means finalizing all other :c:type:`PyThreadState` objects +belonging to the current interpreter and all other +:c:type:`PyInterpreterState` objects. Due to this and the special +nature of the :ref:`"main" interpreter `, +:c:func:`fork` should only be called in that interpreter's "main" +thread, where the CPython global runtime was originally initialized. +The only exception is if :c:func:`exec` will be called immediately +after. + High-level API -------------- diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 212f4d1066c9c..d3bbee23f5081 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -33,6 +33,12 @@ Operating System Utilities that clones the current process. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_BeforeFork()``. + .. versionadded:: 3.7 @@ -44,6 +50,12 @@ Operating System Utilities of whether process cloning was successful. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_AfterFork_Parent()``. + .. versionadded:: 3.7 @@ -55,6 +67,12 @@ Operating System Utilities any chance the process will call back into the Python interpreter. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_AfterFork_Child()``. + .. versionadded:: 3.7 .. seealso:: diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst new file mode 100644 index 0000000000000..49accbc70663a --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst @@ -0,0 +1,3 @@ +Provides more details about the interaction between :c:func:`fork` and +CPython's runtime, focusing just on the C-API. This includes cautions +about where :c:func:`fork` should and shouldn't be called. From webhook-mailer at python.org Fri Nov 15 16:36:54 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 21:36:54 -0000 Subject: [Python-checkins] bpo-38816: Add notes in the C-API docs about fork in subinterpreters. (GH-17176) Message-ID: https://github.com/python/cpython/commit/7a5d4c7a8653cb6be126f87731802aa9a4bc90e2 commit: 7a5d4c7a8653cb6be126f87731802aa9a4bc90e2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T13:36:49-08:00 summary: bpo-38816: Add notes in the C-API docs about fork in subinterpreters. (GH-17176) The C-API docs are a bit sparse on the interplay between C `fork()` and the CPython runtime. This change adds some more information on the subject. https://bugs.python.org/issue38816 (cherry picked from commit 73cdb0c6b2c3861e034004cdc57be5e726876078) Co-authored-by: Eric Snow files: A Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst M Doc/c-api/init.rst M Doc/c-api/sys.rst diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index c9a36ac4f5588..155edba82f96d 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -769,9 +769,19 @@ supports the creation of additional interpreters (using :c:func:`Py_NewInterpreter`), but mixing multiple interpreters and the :c:func:`PyGILState_\*` API is unsupported. + +.. _fork-and-threads: + +Cautions about fork() +--------------------- + Another important thing to note about threads is their behaviour in the face of the C :c:func:`fork` call. On most systems with :c:func:`fork`, after a -process forks only the thread that issued the fork will exist. That also +process forks only the thread that issued the fork will exist. This has a +concrete impact both on how locks must be handled and on all stored state +in CPython's runtime. + +The fact that only the "current" thread remains means any locks held by other threads will never be released. Python solves this for :func:`os.fork` by acquiring the locks it uses internally before the fork, and releasing them afterwards. In addition, it resets any @@ -786,6 +796,17 @@ being held by a thread that is defunct after the fork. :c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not always able to. +The fact that all other threads go away also means that CPython's +runtime state there must be cleaned up properly, which :func:`os.fork` +does. This means finalizing all other :c:type:`PyThreadState` objects +belonging to the current interpreter and all other +:c:type:`PyInterpreterState` objects. Due to this and the special +nature of the :ref:`"main" interpreter `, +:c:func:`fork` should only be called in that interpreter's "main" +thread, where the CPython global runtime was originally initialized. +The only exception is if :c:func:`exec` will be called immediately +after. + High-level API -------------- diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 212f4d1066c9c..d3bbee23f5081 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -33,6 +33,12 @@ Operating System Utilities that clones the current process. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_BeforeFork()``. + .. versionadded:: 3.7 @@ -44,6 +50,12 @@ Operating System Utilities of whether process cloning was successful. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_AfterFork_Parent()``. + .. versionadded:: 3.7 @@ -55,6 +67,12 @@ Operating System Utilities any chance the process will call back into the Python interpreter. Only available on systems where :c:func:`fork` is defined. + .. warning:: + The C :c:func:`fork` call should only be made from the + :ref:`"main" thread ` (of the + :ref:`"main" interpreter `). The same is + true for ``PyOS_AfterFork_Child()``. + .. versionadded:: 3.7 .. seealso:: diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst new file mode 100644 index 0000000000000..49accbc70663a --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst @@ -0,0 +1,3 @@ +Provides more details about the interaction between :c:func:`fork` and +CPython's runtime, focusing just on the C-API. This includes cautions +about where :c:func:`fork` should and shouldn't be called. From webhook-mailer at python.org Fri Nov 15 16:37:31 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 21:37:31 -0000 Subject: [Python-checkins] bpo-38778: Document that os.fork is not allowed in subinterpreters (GH-17123) Message-ID: https://github.com/python/cpython/commit/a4be5aae6e587f5310f1fc0d66d37e032621ce39 commit: a4be5aae6e587f5310f1fc0d66d37e032621ce39 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T13:37:25-08:00 summary: bpo-38778: Document that os.fork is not allowed in subinterpreters (GH-17123) Small docs update for [bpo-34651](https://bugs.python.org/issue34651). Other references to fork (e.g. the PyOS.*Fork functions or discussions of fork() when embedding Python) point back to os.fork, so I don't think any other updates are needed. https://bugs.python.org/issue38778 Automerge-Triggered-By: @ericsnowcurrently (cherry picked from commit b22030073b9327a3aeccb69507694bce078192aa) Co-authored-by: Phil Connell files: A Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index e3f8977f9d076..9d2e8b2eea239 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3475,7 +3475,11 @@ written in Python, such as a mail server's external command delivery program. parent. If an error occurs :exc:`OSError` is raised. Note that some platforms including FreeBSD <= 6.3 and Cygwin have - known issues when using fork() from a thread. + known issues when using ``fork()`` from a thread. + + .. versionchanged:: 3.8 + Calling ``fork()`` in a subinterpreter is no longer supported + (:exc:`RuntimeError` is raised). .. warning:: @@ -3492,6 +3496,10 @@ written in Python, such as a mail server's external command delivery program. master end of the pseudo-terminal. For a more portable approach, use the :mod:`pty` module. If an error occurs :exc:`OSError` is raised. + .. versionchanged:: 3.8 + Calling ``forkpty()`` in a subinterpreter is no longer supported + (:exc:`RuntimeError` is raised). + .. availability:: some flavors of Unix. diff --git a/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst b/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst new file mode 100644 index 0000000000000..053e1d294b70f --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst @@ -0,0 +1 @@ +Document the fact that :exc:`RuntimeError` is raised if :meth:`os.fork` is called in a subinterpreter. From webhook-mailer at python.org Fri Nov 15 16:47:34 2019 From: webhook-mailer at python.org (Tal Einat) Date: Fri, 15 Nov 2019 21:47:34 -0000 Subject: [Python-checkins] Fix the description of isdatadescriptor in inspect.rst (#16645) Message-ID: https://github.com/python/cpython/commit/84f2528d4836f9e8f80f8354cb26341ef7ef0a1b commit: 84f2528d4836f9e8f80f8354cb26341ef7ef0a1b branch: master author: HongWeipeng <961365124 at qq.com> committer: Tal Einat date: 2019-11-15T23:47:26+02:00 summary: Fix the description of isdatadescriptor in inspect.rst (#16645) files: M Doc/library/inspect.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index f6156a0eb370c..10f347dd420f3 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -427,7 +427,7 @@ attributes: Return ``True`` if the object is a data descriptor. - Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. + Data descriptors have a :attr:`~object.__set__` or a :attr:`~object.__delete__` method. Examples are properties (defined in Python), getsets, and members. The latter two are defined in C and there are more specific tests available for those types, which is robust across Python implementations. Typically, data From webhook-mailer at python.org Fri Nov 15 16:54:40 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 21:54:40 -0000 Subject: [Python-checkins] Fix the description of isdatadescriptor in inspect.rst (GH-16645) Message-ID: https://github.com/python/cpython/commit/0b634dfc88d99e34dd871f724b37cc6d58a76e30 commit: 0b634dfc88d99e34dd871f724b37cc6d58a76e30 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T13:54:33-08:00 summary: Fix the description of isdatadescriptor in inspect.rst (GH-16645) (cherry picked from commit 84f2528d4836f9e8f80f8354cb26341ef7ef0a1b) Co-authored-by: HongWeipeng <961365124 at qq.com> files: M Doc/library/inspect.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index f6156a0eb370c..10f347dd420f3 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -427,7 +427,7 @@ attributes: Return ``True`` if the object is a data descriptor. - Data descriptors have both a :attr:`~object.__get__` and a :attr:`~object.__set__` method. + Data descriptors have a :attr:`~object.__set__` or a :attr:`~object.__delete__` method. Examples are properties (defined in Python), getsets, and members. The latter two are defined in C and there are more specific tests available for those types, which is robust across Python implementations. Typically, data From webhook-mailer at python.org Fri Nov 15 17:18:25 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 15 Nov 2019 22:18:25 -0000 Subject: [Python-checkins] Updated missing periods in cmdline.rst (GH-17173) Message-ID: https://github.com/python/cpython/commit/0fe0b88d6eb597c9a929e14ad47a5a9bd99bfe53 commit: 0fe0b88d6eb597c9a929e14ad47a5a9bd99bfe53 branch: master author: Jules Lasne (jlasne) committer: Victor Stinner date: 2019-11-15T23:18:17+01:00 summary: Updated missing periods in cmdline.rst (GH-17173) files: M Doc/using/cmdline.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 457a7fcb6d9e3..9e149806c380f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -457,7 +457,7 @@ Miscellaneous options on a crash. * Enable :ref:`asyncio debug mode `. * Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to - ``True`` + ``True``. * :class:`io.IOBase` destructor logs ``close()`` exceptions. * ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding @@ -780,8 +780,8 @@ conflict. * ``debug``: install debug hooks on top of the :ref:`default memory allocators `. - * ``malloc_debug``: same as ``malloc`` but also install debug hooks - * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks + * ``malloc_debug``: same as ``malloc`` but also install debug hooks. + * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. See the :ref:`default memory allocators ` and the :c:func:`PyMem_SetupDebugHooks` function (install debug hooks on Python From webhook-mailer at python.org Fri Nov 15 17:25:23 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 22:25:23 -0000 Subject: [Python-checkins] Updated missing periods in cmdline.rst (GH-17173) Message-ID: https://github.com/python/cpython/commit/e963c57cfb0c6fb0f1678ac08e206f410ef43a8b commit: e963c57cfb0c6fb0f1678ac08e206f410ef43a8b branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T14:25:18-08:00 summary: Updated missing periods in cmdline.rst (GH-17173) (cherry picked from commit 0fe0b88d6eb597c9a929e14ad47a5a9bd99bfe53) Co-authored-by: Jules Lasne (jlasne) files: M Doc/using/cmdline.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 69169d7b14f9d..c30f6fc7cfd87 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -454,7 +454,7 @@ Miscellaneous options on a crash. * Enable :ref:`asyncio debug mode `. * Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to - ``True`` + ``True``. * :class:`io.IOBase` destructor logs ``close()`` exceptions. * ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding @@ -773,8 +773,8 @@ conflict. * ``debug``: install debug hooks on top of the :ref:`default memory allocators `. - * ``malloc_debug``: same as ``malloc`` but also install debug hooks - * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks + * ``malloc_debug``: same as ``malloc`` but also install debug hooks. + * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. See the :ref:`default memory allocators ` and the :c:func:`PyMem_SetupDebugHooks` function (install debug hooks on Python From webhook-mailer at python.org Fri Nov 15 17:47:22 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 15 Nov 2019 22:47:22 -0000 Subject: [Python-checkins] [3.7] Updated missing periods in cmdline.rst (GH-17173). (GH-17182) Message-ID: https://github.com/python/cpython/commit/208a6a1b1329bf24794732d26d5934c73d670c60 commit: 208a6a1b1329bf24794732d26d5934c73d670c60 branch: 3.7 author: Jules Lasne (jlasne) committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-15T14:47:17-08:00 summary: [3.7] Updated missing periods in cmdline.rst (GH-17173). (GH-17182) (cherry picked from commit 0fe0b88d6eb597c9a929e14ad47a5a9bd99bfe53) Co-authored-by: Jules Lasne (jlasne) files: M Doc/using/cmdline.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 6a60bc4954c62..2c34ac29b68f2 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -449,7 +449,7 @@ Miscellaneous options on a crash. * Enable :ref:`asyncio debug mode `. * Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to - ``True`` + ``True``. * ``-X utf8`` enables UTF-8 mode for operating system interfaces, overriding the default locale-aware mode. ``-X utf8=0`` explicitly disables UTF-8 @@ -745,8 +745,8 @@ conflict. * ``debug``: install debug hooks on top of the :ref:`default memory allocators `. - * ``malloc_debug``: same as ``malloc`` but also install debug hooks - * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks + * ``malloc_debug``: same as ``malloc`` but also install debug hooks. + * ``pymalloc_debug``: same as ``pymalloc`` but also install debug hooks. See the :ref:`default memory allocators ` and the :c:func:`PyMem_SetupDebugHooks` function (install debug hooks on Python From webhook-mailer at python.org Fri Nov 15 18:25:17 2019 From: webhook-mailer at python.org (Steve Dower) Date: Fri, 15 Nov 2019 23:25:17 -0000 Subject: [Python-checkins] bpo-38453: Ensure ntpath.realpath correctly resolves relative paths (GH-16967) Message-ID: https://github.com/python/cpython/commit/66c0f01f98fd6db0a4b1e789b9db9c7247a24ba9 commit: 66c0f01f98fd6db0a4b1e789b9db9c7247a24ba9 branch: 3.8 author: Steve Dower committer: GitHub date: 2019-11-15T15:25:03-08:00 summary: bpo-38453: Ensure ntpath.realpath correctly resolves relative paths (GH-16967) Ensure isabs() is always True for \\?\ prefixed paths Avoid unnecessary usage of readlink() to avoid resolving broken links incorrectly Ensure shutil tests run in test directory files: A Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst M Lib/ntpath.py M Lib/test/test_ntpath.py M Lib/test/test_shutil.py diff --git a/Lib/ntpath.py b/Lib/ntpath.py index d4ecff97c9528..6f771773a7d1b 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -61,6 +61,14 @@ def normcase(s): def isabs(s): """Test whether a path is absolute""" s = os.fspath(s) + # Paths beginning with \\?\ are always absolute, but do not + # necessarily contain a drive. + if isinstance(s, bytes): + if s.replace(b'/', b'\\').startswith(b'\\\\?\\'): + return True + else: + if s.replace('/', '\\').startswith('\\\\?\\'): + return True s = splitdrive(s)[1] return len(s) > 0 and s[0] in _get_bothseps(s) @@ -526,10 +534,7 @@ def abspath(path): # realpath is a no-op on systems without _getfinalpathname support. realpath = abspath else: - def _readlink_deep(path, seen=None): - if seen is None: - seen = set() - + def _readlink_deep(path): # These error codes indicate that we should stop reading links and # return the path we currently have. # 1: ERROR_INVALID_FUNCTION @@ -546,10 +551,22 @@ def _readlink_deep(path, seen=None): # 4393: ERROR_REPARSE_TAG_INVALID allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393 + seen = set() while normcase(path) not in seen: seen.add(normcase(path)) try: + old_path = path path = _nt_readlink(path) + # Links may be relative, so resolve them against their + # own location + if not isabs(path): + # If it's something other than a symlink, we don't know + # what it's actually going to be resolved against, so + # just return the old path. + if not islink(old_path): + path = old_path + break + path = normpath(join(dirname(old_path), path)) except OSError as ex: if ex.winerror in allowed_winerror: break @@ -579,23 +596,31 @@ def _getfinalpathname_nonstrict(path): # Non-strict algorithm is to find as much of the target directory # as we can and join the rest. tail = '' - seen = set() while path: try: - path = _readlink_deep(path, seen) path = _getfinalpathname(path) return join(path, tail) if tail else path except OSError as ex: if ex.winerror not in allowed_winerror: raise + try: + # The OS could not resolve this path fully, so we attempt + # to follow the link ourselves. If we succeed, join the tail + # and return. + new_path = _readlink_deep(path) + if new_path != path: + return join(new_path, tail) if tail else new_path + except OSError: + # If we fail to readlink(), let's keep traversing + pass path, name = split(path) # TODO (bpo-38186): Request the real file name from the directory # entry using FindFirstFileW. For now, we will return the path # as best we have it if path and not name: - return abspath(path + tail) + return path + tail tail = join(name, tail) if tail else name - return abspath(tail) + return tail def realpath(path): path = normpath(path) @@ -604,12 +629,20 @@ def realpath(path): unc_prefix = b'\\\\?\\UNC\\' new_unc_prefix = b'\\\\' cwd = os.getcwdb() + # bpo-38081: Special case for realpath(b'nul') + if normcase(path) == normcase(os.fsencode(devnull)): + return b'\\\\.\\NUL' else: prefix = '\\\\?\\' unc_prefix = '\\\\?\\UNC\\' new_unc_prefix = '\\\\' cwd = os.getcwd() + # bpo-38081: Special case for realpath('nul') + if normcase(path) == normcase(devnull): + return '\\\\.\\NUL' had_prefix = path.startswith(prefix) + if not had_prefix and not isabs(path): + path = join(cwd, path) try: path = _getfinalpathname(path) initial_winerror = 0 diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index e0ec441985230..a84b94c9badbe 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -286,14 +286,16 @@ def test_realpath_broken_symlinks(self): ABSTFN + r"\missing") self.assertPathEqual(ntpath.realpath(r"broken\foo"), ABSTFN + r"\missing\foo") + # bpo-38453: We no longer recursively resolve segments of relative + # symlinks that the OS cannot resolve. self.assertPathEqual(ntpath.realpath(r"broken1"), - ABSTFN + r"\missing\bar") + ABSTFN + r"\broken\bar") self.assertPathEqual(ntpath.realpath(r"broken1\baz"), - ABSTFN + r"\missing\bar\baz") + ABSTFN + r"\broken\bar\baz") self.assertPathEqual(ntpath.realpath("broken2"), - ABSTFN + r"\missing") + ABSTFN + r"\self\self\missing") self.assertPathEqual(ntpath.realpath("broken3"), - ABSTFN + r"\missing") + ABSTFN + r"\subdir\parent\subdir\parent\missing") self.assertPathEqual(ntpath.realpath("broken4"), ABSTFN + r"\missing") self.assertPathEqual(ntpath.realpath("broken5"), @@ -304,13 +306,13 @@ def test_realpath_broken_symlinks(self): self.assertPathEqual(ntpath.realpath(rb"broken\foo"), os.fsencode(ABSTFN + r"\missing\foo")) self.assertPathEqual(ntpath.realpath(rb"broken1"), - os.fsencode(ABSTFN + r"\missing\bar")) + os.fsencode(ABSTFN + r"\broken\bar")) self.assertPathEqual(ntpath.realpath(rb"broken1\baz"), - os.fsencode(ABSTFN + r"\missing\bar\baz")) + os.fsencode(ABSTFN + r"\broken\bar\baz")) self.assertPathEqual(ntpath.realpath(b"broken2"), - os.fsencode(ABSTFN + r"\missing")) + os.fsencode(ABSTFN + r"\self\self\missing")) self.assertPathEqual(ntpath.realpath(rb"broken3"), - os.fsencode(ABSTFN + r"\missing")) + os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing")) self.assertPathEqual(ntpath.realpath(b"broken4"), os.fsencode(ABSTFN + r"\missing")) self.assertPathEqual(ntpath.realpath(b"broken5"), @@ -319,8 +321,8 @@ def test_realpath_broken_symlinks(self): @support.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_symlink_loops(self): - # Bug #930024, return the path unchanged if we get into an infinite - # symlink loop. + # Symlink loops are non-deterministic as to which path is returned, but + # it will always be the fully resolved path of one member of the cycle ABSTFN = ntpath.abspath(support.TESTFN) self.addCleanup(support.unlink, ABSTFN) self.addCleanup(support.unlink, ABSTFN + "1") @@ -332,8 +334,6 @@ def test_realpath_symlink_loops(self): os.symlink(ABSTFN, ABSTFN) self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN) - # cycles are non-deterministic as to which path is returned, but - # it will always be the fully resolved path of one member of the cycle os.symlink(ABSTFN + "1", ABSTFN + "2") os.symlink(ABSTFN + "2", ABSTFN + "1") expected = (ABSTFN + "1", ABSTFN + "2") @@ -402,6 +402,34 @@ def test_realpath_symlink_prefix(self): def test_realpath_nul(self): tester("ntpath.realpath('NUL')", r'\\.\NUL') + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + def test_realpath_cwd(self): + ABSTFN = ntpath.abspath(support.TESTFN) + + support.unlink(ABSTFN) + support.rmtree(ABSTFN) + os.mkdir(ABSTFN) + self.addCleanup(support.rmtree, ABSTFN) + + test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") + test_dir_short = ntpath.join(ABSTFN, "MYVERY~1") + test_file_long = ntpath.join(test_dir_long, "file.txt") + test_file_short = ntpath.join(test_dir_short, "file.txt") + + os.mkdir(test_dir_long) + + with open(test_file_long, "wb") as f: + f.write(b"content") + + self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short)) + + with support.change_cwd(test_dir_long): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + with support.change_cwd(test_dir_long.lower()): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + with support.change_cwd(test_dir_short): + self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) + def test_expandvars(self): with support.EnvironmentVarGuard() as env: env.clear() diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 636e3bd979559..b98e7dc798abe 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -177,7 +177,10 @@ def mkdtemp(self): Returns the path of the directory. """ - d = tempfile.mkdtemp() + basedir = None + if sys.platform == "win32": + basedir = os.path.realpath(os.getcwd()) + d = tempfile.mkdtemp(dir=basedir) self.tempdirs.append(d) return d @@ -1788,8 +1791,11 @@ class TestMove(unittest.TestCase): def setUp(self): filename = "foo" - self.src_dir = tempfile.mkdtemp() - self.dst_dir = tempfile.mkdtemp() + basedir = None + if sys.platform == "win32": + basedir = os.path.realpath(os.getcwd()) + self.src_dir = tempfile.mkdtemp(dir=basedir) + self.dst_dir = tempfile.mkdtemp(dir=basedir) self.src_file = os.path.join(self.src_dir, filename) self.dst_file = os.path.join(self.dst_dir, filename) with open(self.src_file, "wb") as f: diff --git a/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst b/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst new file mode 100644 index 0000000000000..deacb03c6f01d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst @@ -0,0 +1 @@ +Ensure ntpath.realpath() correctly resolves relative paths. From webhook-mailer at python.org Fri Nov 15 19:03:26 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Sat, 16 Nov 2019 00:03:26 -0000 Subject: [Python-checkins] bpo-38644: Add _PyEval_EvalCode() (GH-17183) Message-ID: https://github.com/python/cpython/commit/b5e170f127b57d5b0a4fb58f316acd6191509dce commit: b5e170f127b57d5b0a4fb58f316acd6191509dce branch: master author: Victor Stinner committer: GitHub date: 2019-11-16T01:03:22+01:00 summary: bpo-38644: Add _PyEval_EvalCode() (GH-17183) _PyFunction_Vectorcall() now pass tstate to function calls. files: M Include/internal/pycore_ceval.h M Objects/call.c M Python/ceval.c diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 7adb87214a058..857fc0b2524fe 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -43,6 +43,16 @@ _PyEval_EvalFrame(PyThreadState *tstate, struct _frame *f, int throwflag) return tstate->interp->eval_frame(f, throwflag); } +extern PyObject *_PyEval_EvalCode( + PyThreadState *tstate, + PyObject *_co, PyObject *globals, PyObject *locals, + PyObject *const *args, Py_ssize_t argcount, + PyObject *const *kwnames, PyObject *const *kwargs, + Py_ssize_t kwcount, int kwstep, + PyObject *const *defs, Py_ssize_t defcount, + PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname); + #ifdef __cplusplus } #endif diff --git a/Objects/call.c b/Objects/call.c index ae08d1824468d..0f8cb5aa246b0 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -302,13 +302,12 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) /* --- PyFunction call functions ---------------------------------- */ static PyObject* _Py_HOT_FUNCTION -function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs, +function_code_fastcall(PyThreadState *tstate, PyCodeObject *co, + PyObject *const *args, Py_ssize_t nargs, PyObject *globals) { - assert(globals != NULL); - - PyThreadState *tstate = _PyThreadState_GET(); assert(tstate != NULL); + assert(globals != NULL); /* XXX Perhaps we should create a specialized _PyFrame_New_NoTrack() that doesn't take locals, but does @@ -344,57 +343,61 @@ PyObject * _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, size_t nargsf, PyObject *kwnames) { - PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); - PyObject *globals = PyFunction_GET_GLOBALS(func); - PyObject *argdefs = PyFunction_GET_DEFAULTS(func); - PyObject *kwdefs, *closure, *name, *qualname; - PyObject **d; - Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - Py_ssize_t nd; - assert(PyFunction_Check(func)); + assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); - assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); + Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); assert((nargs == 0 && nkwargs == 0) || stack != NULL); /* kwnames must only contain strings and all keys must be unique */ + PyThreadState *tstate = _PyThreadState_GET(); + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + if (co->co_kwonlyargcount == 0 && nkwargs == 0 && (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { if (argdefs == NULL && co->co_argcount == nargs) { - return function_code_fastcall(co, stack, nargs, globals); + return function_code_fastcall(tstate, co, stack, nargs, globals); } else if (nargs == 0 && argdefs != NULL && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ stack = _PyTuple_ITEMS(argdefs); - return function_code_fastcall(co, stack, PyTuple_GET_SIZE(argdefs), + return function_code_fastcall(tstate, co, + stack, PyTuple_GET_SIZE(argdefs), globals); } } - kwdefs = PyFunction_GET_KW_DEFAULTS(func); - closure = PyFunction_GET_CLOSURE(func); - name = ((PyFunctionObject *)func) -> func_name; - qualname = ((PyFunctionObject *)func) -> func_qualname; + PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); + PyObject *closure = PyFunction_GET_CLOSURE(func); + PyObject *name = ((PyFunctionObject *)func) -> func_name; + PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname; + PyObject **d; + Py_ssize_t nd; if (argdefs != NULL) { d = _PyTuple_ITEMS(argdefs); nd = PyTuple_GET_SIZE(argdefs); + assert(nd <= INT_MAX); } else { d = NULL; nd = 0; } - return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL, - stack, nargs, - nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, - stack + nargs, - nkwargs, 1, - d, (int)nd, kwdefs, - closure, name, qualname); + return _PyEval_EvalCode(tstate, + (PyObject*)co, globals, (PyObject *)NULL, + stack, nargs, + nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, + stack + nargs, + nkwargs, 1, + d, (int)nd, kwdefs, + closure, name, qualname); } diff --git a/Python/ceval.c b/Python/ceval.c index 11d25a53d527a..9f4b43615e28f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4045,7 +4045,8 @@ positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, the test in the if statements in Misc/gdbinit (pystack and pystackv). */ PyObject * -_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, +_PyEval_EvalCode(PyThreadState *tstate, + PyObject *_co, PyObject *globals, PyObject *locals, PyObject *const *args, Py_ssize_t argcount, PyObject *const *kwnames, PyObject *const *kwargs, Py_ssize_t kwcount, int kwstep, @@ -4053,6 +4054,8 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *kwdefs, PyObject *closure, PyObject *name, PyObject *qualname) { + assert(tstate != NULL); + PyCodeObject* co = (PyCodeObject*)_co; PyFrameObject *f; PyObject *retval = NULL; @@ -4062,9 +4065,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, Py_ssize_t i, j, n; PyObject *kwdict; - PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); - if (globals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "PyEval_EvalCodeEx: NULL globals"); @@ -4319,6 +4319,26 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, return retval; } + +PyObject * +_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, + PyObject *const *args, Py_ssize_t argcount, + PyObject *const *kwnames, PyObject *const *kwargs, + Py_ssize_t kwcount, int kwstep, + PyObject *const *defs, Py_ssize_t defcount, + PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_EvalCode(tstate, _co, globals, locals, + args, argcount, + kwnames, kwargs, + kwcount, kwstep, + defs, defcount, + kwdefs, closure, + name, qualname); +} + PyObject * PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *const *args, int argcount, From webhook-mailer at python.org Fri Nov 15 19:04:04 2019 From: webhook-mailer at python.org (Steve Dower) Date: Sat, 16 Nov 2019 00:04:04 -0000 Subject: [Python-checkins] bpo-38453: Ensure correct short path is obtained for test (GH-17184) Message-ID: https://github.com/python/cpython/commit/7c6130c8c36c941255365e5414c956fc919b8629 commit: 7c6130c8c36c941255365e5414c956fc919b8629 branch: master author: Steve Dower committer: GitHub date: 2019-11-15T16:04:00-08:00 summary: bpo-38453: Ensure correct short path is obtained for test (GH-17184) files: M Lib/test/test_ntpath.py diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index a84b94c9badbe..4a02db281724e 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -22,6 +22,23 @@ else: HAVE_GETFINALPATHNAME = True +try: + import ctypes +except ImportError: + HAVE_GETSHORTPATHNAME = False +else: + HAVE_GETSHORTPATHNAME = True + def _getshortpathname(path): + GSPN = ctypes.WinDLL("kernel32", use_last_error=True).GetShortPathNameW + GSPN.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32] + GSPN.restype = ctypes.c_uint32 + result_len = GSPN(path, None, 0) + if not result_len: + raise OSError("failed to get short path name 0x{:08X}" + .format(ctypes.get_last_error())) + result = ctypes.create_unicode_buffer(result_len) + result_len = GSPN(path, result, result_len) + return result[:result_len] def _norm(path): if isinstance(path, (bytes, str, os.PathLike)): @@ -403,6 +420,7 @@ def test_realpath_nul(self): tester("ntpath.realpath('NUL')", r'\\.\NUL') @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') def test_realpath_cwd(self): ABSTFN = ntpath.abspath(support.TESTFN) @@ -412,12 +430,12 @@ def test_realpath_cwd(self): self.addCleanup(support.rmtree, ABSTFN) test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") - test_dir_short = ntpath.join(ABSTFN, "MYVERY~1") + os.mkdir(test_dir_long) + + test_dir_short = _getshortpathname(test_dir_long) test_file_long = ntpath.join(test_dir_long, "file.txt") test_file_short = ntpath.join(test_dir_short, "file.txt") - os.mkdir(test_dir_long) - with open(test_file_long, "wb") as f: f.write(b"content") From webhook-mailer at python.org Fri Nov 15 19:04:48 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Sat, 16 Nov 2019 00:04:48 -0000 Subject: [Python-checkins] bpo-38644: Cleanup ceval.h (GH-17185) Message-ID: https://github.com/python/cpython/commit/51edf8aaa2e17626f9690ed29d25945fc03016b9 commit: 51edf8aaa2e17626f9690ed29d25945fc03016b9 branch: master author: Victor Stinner committer: GitHub date: 2019-11-16T01:04:44+01:00 summary: bpo-38644: Cleanup ceval.h (GH-17185) Move CPython API (Py_LIMITED_API macro not defined) from ceval.h to cpython/ceval.h files: M Include/ceval.h M Include/cpython/ceval.h diff --git a/Include/ceval.h b/Include/ceval.h index 8da779ba97b73..62c6489ed1c35 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -28,16 +28,6 @@ Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction( Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallMethod( PyObject *obj, const char *name, const char *format, ...); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); -PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); -PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); -PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); -PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); -#endif - struct _frame; /* Avoid including frameobject.h */ PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); @@ -45,15 +35,6 @@ PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); -#ifndef Py_LIMITED_API -/* Helper to look up a builtin object */ -PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); -/* Look at the current frame's (if any) code's co_flags, and turn on - the corresponding compiler flags in cf->cf_flags. Return 1 if any - flag was set, else return 0. */ -PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); -#endif - PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); PyAPI_FUNC(int) Py_MakePendingCalls(void); @@ -101,9 +82,6 @@ PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc); -#endif /* Interface for threads. @@ -160,15 +138,6 @@ Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void); PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); -PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); -#endif - -#ifndef Py_LIMITED_API -PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); -#endif - #define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ _save = PyEval_SaveThread(); @@ -177,11 +146,6 @@ PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ } -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); -PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); -#endif - /* Masks and values used by FORMAT_VALUE opcode. */ #define FVC_MASK 0x3 #define FVC_NONE 0x0 diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 1e2c4577a78ff..e601304589f76 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -6,6 +6,31 @@ extern "C" { #endif +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); +PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); + +/* Helper to look up a builtin object */ +PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *); +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); + +PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc); + +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); + +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 *); + PyAPI_DATA(int) _Py_CheckRecursionLimit; #ifdef USE_STACKCHECK From webhook-mailer at python.org Fri Nov 15 19:21:32 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 00:21:32 -0000 Subject: [Python-checkins] bpo-38453: Ensure correct short path is obtained for test (GH-17184) Message-ID: https://github.com/python/cpython/commit/6f602fbd3568ed7bebadfa3c7d3de40a271216f9 commit: 6f602fbd3568ed7bebadfa3c7d3de40a271216f9 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-15T16:21:27-08:00 summary: bpo-38453: Ensure correct short path is obtained for test (GH-17184) (cherry picked from commit 7c6130c8c36c941255365e5414c956fc919b8629) Co-authored-by: Steve Dower files: M Lib/test/test_ntpath.py diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index a84b94c9badbe..4a02db281724e 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -22,6 +22,23 @@ else: HAVE_GETFINALPATHNAME = True +try: + import ctypes +except ImportError: + HAVE_GETSHORTPATHNAME = False +else: + HAVE_GETSHORTPATHNAME = True + def _getshortpathname(path): + GSPN = ctypes.WinDLL("kernel32", use_last_error=True).GetShortPathNameW + GSPN.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32] + GSPN.restype = ctypes.c_uint32 + result_len = GSPN(path, None, 0) + if not result_len: + raise OSError("failed to get short path name 0x{:08X}" + .format(ctypes.get_last_error())) + result = ctypes.create_unicode_buffer(result_len) + result_len = GSPN(path, result, result_len) + return result[:result_len] def _norm(path): if isinstance(path, (bytes, str, os.PathLike)): @@ -403,6 +420,7 @@ def test_realpath_nul(self): tester("ntpath.realpath('NUL')", r'\\.\NUL') @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') + @unittest.skipUnless(HAVE_GETSHORTPATHNAME, 'need _getshortpathname') def test_realpath_cwd(self): ABSTFN = ntpath.abspath(support.TESTFN) @@ -412,12 +430,12 @@ def test_realpath_cwd(self): self.addCleanup(support.rmtree, ABSTFN) test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName") - test_dir_short = ntpath.join(ABSTFN, "MYVERY~1") + os.mkdir(test_dir_long) + + test_dir_short = _getshortpathname(test_dir_long) test_file_long = ntpath.join(test_dir_long, "file.txt") test_file_short = ntpath.join(test_dir_short, "file.txt") - os.mkdir(test_dir_long) - with open(test_file_long, "wb") as f: f.write(b"content") From webhook-mailer at python.org Sat Nov 16 11:01:03 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 16 Nov 2019 16:01:03 -0000 Subject: [Python-checkins] bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991) Message-ID: https://github.com/python/cpython/commit/5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203 commit: 5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203 branch: master author: Serhiy Storchaka committer: GitHub date: 2019-11-16T18:00:57+02:00 summary: bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991) files: A Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO.rst M Lib/test/test_math.py M Modules/mathmodule.c diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index c237bc1942e65..f832246dda322 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -240,6 +240,13 @@ def result_check(expected, got, ulp_tol=5, abs_tol=0.0): else: return None +class FloatLike: + def __init__(self, value): + self.value = value + + def __float__(self): + return self.value + class IntSubclass(int): pass @@ -397,12 +404,14 @@ def testAtan2(self): def testCeil(self): self.assertRaises(TypeError, math.ceil) self.assertEqual(int, type(math.ceil(0.5))) - self.ftest('ceil(0.5)', math.ceil(0.5), 1) - self.ftest('ceil(1.0)', math.ceil(1.0), 1) - self.ftest('ceil(1.5)', math.ceil(1.5), 2) - self.ftest('ceil(-0.5)', math.ceil(-0.5), 0) - self.ftest('ceil(-1.0)', math.ceil(-1.0), -1) - self.ftest('ceil(-1.5)', math.ceil(-1.5), -1) + self.assertEqual(math.ceil(0.5), 1) + self.assertEqual(math.ceil(1.0), 1) + self.assertEqual(math.ceil(1.5), 2) + self.assertEqual(math.ceil(-0.5), 0) + self.assertEqual(math.ceil(-1.0), -1) + self.assertEqual(math.ceil(-1.5), -1) + self.assertEqual(math.ceil(0.0), 0) + self.assertEqual(math.ceil(-0.0), 0) #self.assertEqual(math.ceil(INF), INF) #self.assertEqual(math.ceil(NINF), NINF) #self.assertTrue(math.isnan(math.ceil(NAN))) @@ -410,9 +419,14 @@ def testCeil(self): class TestCeil: def __ceil__(self): return 42 + class FloatCeil(float): + def __ceil__(self): + return 42 class TestNoCeil: pass - self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42) + self.assertEqual(math.ceil(TestCeil()), 42) + self.assertEqual(math.ceil(FloatCeil()), 42) + self.assertEqual(math.ceil(FloatLike(42.5)), 43) self.assertRaises(TypeError, math.ceil, TestNoCeil()) t = TestNoCeil() @@ -536,16 +550,12 @@ def testFactorialHugeInputs(self): def testFloor(self): self.assertRaises(TypeError, math.floor) self.assertEqual(int, type(math.floor(0.5))) - self.ftest('floor(0.5)', math.floor(0.5), 0) - self.ftest('floor(1.0)', math.floor(1.0), 1) - self.ftest('floor(1.5)', math.floor(1.5), 1) - self.ftest('floor(-0.5)', math.floor(-0.5), -1) - self.ftest('floor(-1.0)', math.floor(-1.0), -1) - self.ftest('floor(-1.5)', math.floor(-1.5), -2) - # pow() relies on floor() to check for integers - # This fails on some platforms - so check it here - self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167) - self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167) + self.assertEqual(math.floor(0.5), 0) + self.assertEqual(math.floor(1.0), 1) + self.assertEqual(math.floor(1.5), 1) + self.assertEqual(math.floor(-0.5), -1) + self.assertEqual(math.floor(-1.0), -1) + self.assertEqual(math.floor(-1.5), -2) #self.assertEqual(math.ceil(INF), INF) #self.assertEqual(math.ceil(NINF), NINF) #self.assertTrue(math.isnan(math.floor(NAN))) @@ -553,9 +563,14 @@ def testFloor(self): class TestFloor: def __floor__(self): return 42 + class FloatFloor(float): + def __floor__(self): + return 42 class TestNoFloor: pass - self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42) + self.assertEqual(math.floor(TestFloor()), 42) + self.assertEqual(math.floor(FloatFloor()), 42) + self.assertEqual(math.floor(FloatLike(41.9)), 41) self.assertRaises(TypeError, math.floor, TestNoFloor()) t = TestNoFloor() @@ -1448,17 +1463,21 @@ def test_trunc(self): self.assertEqual(math.trunc(-0.999999), -0) self.assertEqual(math.trunc(-100.999), -100) - class TestTrunc(object): + class TestTrunc: def __trunc__(self): return 23 - - class TestNoTrunc(object): + class FloatTrunc(float): + def __trunc__(self): + return 23 + class TestNoTrunc: pass self.assertEqual(math.trunc(TestTrunc()), 23) + self.assertEqual(math.trunc(FloatTrunc()), 23) self.assertRaises(TypeError, math.trunc) self.assertRaises(TypeError, math.trunc, 1, 2) + self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) self.assertRaises(TypeError, math.trunc, TestNoTrunc()) def testIsfinite(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO.rst new file mode 100644 index 0000000000000..4432afde64d6e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO.rst @@ -0,0 +1,2 @@ +Optimized :func:`math.floor()`, :func:`math.ceil()` and :func:`math.trunc()` +for floats. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index e1b46ec384a37..eaaeedbef3823 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1013,12 +1013,6 @@ math_1(PyObject *arg, double (*func) (double), int can_overflow) return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); } -static PyObject * -math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) -{ - return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); -} - static PyObject * math_2(PyObject *const *args, Py_ssize_t nargs, double (*func) (double, double), const char *funcname) @@ -1112,17 +1106,22 @@ math_ceil(PyObject *module, PyObject *number) /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ { _Py_IDENTIFIER(__ceil__); - PyObject *method, *result; - method = _PyObject_LookupSpecial(number, &PyId___ceil__); - if (method == NULL) { + if (!PyFloat_CheckExact(number)) { + PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__); + if (method != NULL) { + PyObject *result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; + } if (PyErr_Occurred()) return NULL; - return math_1_to_int(number, ceil, 0); } - result = _PyObject_CallNoArg(method); - Py_DECREF(method); - return result; + double x = PyFloat_AsDouble(number); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + + return PyLong_FromDouble(ceil(x)); } FUNC2(copysign, copysign, @@ -1170,17 +1169,22 @@ math_floor(PyObject *module, PyObject *number) /*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/ { _Py_IDENTIFIER(__floor__); - PyObject *method, *result; - method = _PyObject_LookupSpecial(number, &PyId___floor__); - if (method == NULL) { + if (!PyFloat_CheckExact(number)) { + PyObject *method = _PyObject_LookupSpecial(number, &PyId___floor__); + if (method != NULL) { + PyObject *result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; + } if (PyErr_Occurred()) return NULL; - return math_1_to_int(number, floor, 0); } - result = _PyObject_CallNoArg(method); - Py_DECREF(method); - return result; + double x = PyFloat_AsDouble(number); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + + return PyLong_FromDouble(floor(x)); } FUNC1A(gamma, m_tgamma, @@ -2061,6 +2065,10 @@ math_trunc(PyObject *module, PyObject *x) _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; + if (PyFloat_CheckExact(x)) { + return PyFloat_Type.tp_as_number->nb_int(x); + } + if (Py_TYPE(x)->tp_dict == NULL) { if (PyType_Ready(Py_TYPE(x)) < 0) return NULL; From webhook-mailer at python.org Sat Nov 16 11:55:34 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 16 Nov 2019 16:55:34 -0000 Subject: [Python-checkins] bpo-38650: Constify PyStructSequence_UnnamedField. (GH-17005) Message-ID: https://github.com/python/cpython/commit/bd44a7ead9f7336d7bb45f186b2b6ca0300154f7 commit: bd44a7ead9f7336d7bb45f186b2b6ca0300154f7 branch: master author: Serhiy Storchaka committer: GitHub date: 2019-11-16T18:55:29+02:00 summary: bpo-38650: Constify PyStructSequence_UnnamedField. (GH-17005) Make it a constant and referring to a constant string. files: A Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst M Doc/c-api/tuple.rst M Doc/whatsnew/3.9.rst M Include/structseq.h M Objects/structseq.c diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 25df3974e870e..62bc9a565071d 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -182,10 +182,13 @@ type. +-----------+------------------+-----------------------------------------+ -.. c:var:: char* PyStructSequence_UnnamedField +.. c:var:: const char * const PyStructSequence_UnnamedField Special value for a field name to leave it unnamed. + .. versionchanged:: 3.9 + The type was changed from ``char *``. + .. c:function:: PyObject* PyStructSequence_New(PyTypeObject *type) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index b1beb0be090cf..6e9ddc5684045 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -215,6 +215,9 @@ Build and C API Changes way to call a callable Python object without any argument. (Contributed by Victor Stinner in :issue:`37194`.) +* The global variable :c:data:`PyStructSequence_UnnamedField` is now a constant + and refers to a constant string. + (Contributed by Serhiy Storchaka in :issue:`38650`.) Deprecated diff --git a/Include/structseq.h b/Include/structseq.h index e5e5d5c5735e9..8f51c89163a4e 100644 --- a/Include/structseq.h +++ b/Include/structseq.h @@ -19,7 +19,7 @@ typedef struct PyStructSequence_Desc { int n_in_sequence; } PyStructSequence_Desc; -extern char* PyStructSequence_UnnamedField; +extern const char * const PyStructSequence_UnnamedField; #ifndef Py_LIMITED_API PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, diff --git a/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst b/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst new file mode 100644 index 0000000000000..55b9c13ca3d0c --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst @@ -0,0 +1,2 @@ +The global variable :c:data:`PyStructSequence_UnnamedField` is now a +constant and refers to a constant string. diff --git a/Objects/structseq.c b/Objects/structseq.c index c158afccb97fd..c86fbe50b972c 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -18,7 +18,7 @@ static const char unnamed_fields_key[] = "n_unnamed_fields"; /* Fields with this name have only a field index, not a field name. They are only allowed for indices < n_visible_fields. */ -char *PyStructSequence_UnnamedField = "unnamed field"; +const char * const PyStructSequence_UnnamedField = "unnamed field"; _Py_IDENTIFIER(n_sequence_fields); _Py_IDENTIFIER(n_fields); _Py_IDENTIFIER(n_unnamed_fields); From webhook-mailer at python.org Sat Nov 16 11:57:01 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 16 Nov 2019 16:57:01 -0000 Subject: [Python-checkins] bpo-28286: Deprecate opening GzipFile for writing implicitly. (GH-16417) Message-ID: https://github.com/python/cpython/commit/a0652328a26757a90d63697b5c01f5427b1132b5 commit: a0652328a26757a90d63697b5c01f5427b1132b5 branch: master author: Serhiy Storchaka committer: GitHub date: 2019-11-16T18:56:57+02:00 summary: bpo-28286: Deprecate opening GzipFile for writing implicitly. (GH-16417) Always specify the mode argument for writing. files: A Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst M Doc/library/gzip.rst M Doc/whatsnew/3.9.rst M Lib/gzip.py M Lib/test/test_gzip.py diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 3349a94446d0c..33c40676f747c 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -88,7 +88,8 @@ The module defines the following items: The *mode* argument can be any of ``'r'``, ``'rb'``, ``'a'``, ``'ab'``, ``'w'``, ``'wb'``, ``'x'``, or ``'xb'``, depending on whether the file will be read or written. The default is the mode of *fileobj* if discernible; otherwise, the - default is ``'rb'``. + default is ``'rb'``. In future Python releases the mode of *fileobj* will + not be used. It is better to always specify *mode* for writing. Note that the file is always opened in binary mode. To open a compressed file in text mode, use :func:`.open` (or wrap your :class:`GzipFile` with an @@ -164,6 +165,10 @@ The module defines the following items: .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. deprecated:: 3.9 + Opening :class:`GzipFile` for writing without specifying the *mode* + argument is deprecated. + .. function:: compress(data, compresslevel=9, *, mtime=None) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 6e9ddc5684045..ddb295f845c75 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -239,6 +239,12 @@ Deprecated the module will restrict its seeds to :const:`None`, :class:`int`, :class:`float`, :class:`str`, :class:`bytes`, and :class:`bytearray`. +* Opening the :class:`~gzip.GzipFile` file for writing without specifying + the *mode* argument is deprecated. In future Python versions it will always + be opened for reading by default. Specify the *mode* argument for opening + it for writing and silencing a warning. + (Contributed by Serhiy Storchaka in :issue:`28286`.) + * Deprecated the ``split()`` method of :class:`_tkinter.TkappType` in favour of the ``splitlist()`` method which has more consistent and predicable behavior. diff --git a/Lib/gzip.py b/Lib/gzip.py index 2968f475efad3..e60d8ad5995b3 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -177,6 +177,7 @@ def __init__(self, filename=None, mode=None, filename = '' else: filename = os.fspath(filename) + origmode = mode if mode is None: mode = getattr(fileobj, 'mode', 'rb') @@ -187,6 +188,13 @@ def __init__(self, filename=None, mode=None, self.name = filename elif mode.startswith(('w', 'a', 'x')): + if origmode is None: + import warnings + warnings.warn( + "GzipFile was opened for writing, but this will " + "change in future Python releases. " + "Specify the mode argument for opening it for writing.", + FutureWarning, 2) self.mode = WRITE self._init_write(filename) self.compress = zlib.compressobj(compresslevel, diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 48a36a30913f6..57d851cf9cf15 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -469,7 +469,9 @@ def test_fileobj_mode(self): if "x" in mode: support.unlink(self.filename) with open(self.filename, mode) as f: - with gzip.GzipFile(fileobj=f) as g: + with self.assertWarns(FutureWarning): + g = gzip.GzipFile(fileobj=f) + with g: self.assertEqual(g.mode, gzip.WRITE) def test_bytes_filename(self): diff --git a/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst b/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst new file mode 100644 index 0000000000000..ee9721587eeb9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst @@ -0,0 +1,2 @@ +Deprecate opening :class:`~gzip.GzipFile` for writing implicitly. Always +specify the *mode* argument for writing. From webhook-mailer at python.org Sat Nov 16 13:14:49 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Sat, 16 Nov 2019 18:14:49 -0000 Subject: [Python-checkins] Fix typo in Lib/socketserver.py (GH-17024) Message-ID: https://github.com/python/cpython/commit/d0acdfcf345b44b01e59f3623dcdab6279de686a commit: d0acdfcf345b44b01e59f3623dcdab6279de686a branch: master author: Jason (Perry) Taylor committer: Victor Stinner date: 2019-11-16T19:14:45+01:00 summary: Fix typo in Lib/socketserver.py (GH-17024) changed 'This is bad class design, but save some typing' into 'This is bad class design, but saves some typing'. files: M Lib/socketserver.py diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 905df9319e2fa..1ad028fa4d08c 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -24,7 +24,7 @@ The classes in this module favor the server type that is simplest to write: a synchronous TCP/IP server. This is bad class design, but -save some typing. (There's also the issue that a deep class hierarchy +saves some typing. (There's also the issue that a deep class hierarchy slows down method lookups.) There are five classes in an inheritance diagram, four of which represent From webhook-mailer at python.org Sat Nov 16 13:32:42 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 18:32:42 -0000 Subject: [Python-checkins] Fix typo in Lib/socketserver.py (GH-17024) Message-ID: https://github.com/python/cpython/commit/5469bc0ea77ed00fd2f98807f3035e835ad8bf0f commit: 5469bc0ea77ed00fd2f98807f3035e835ad8bf0f branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T10:32:37-08:00 summary: Fix typo in Lib/socketserver.py (GH-17024) changed 'This is bad class design, but save some typing' into 'This is bad class design, but saves some typing'. (cherry picked from commit d0acdfcf345b44b01e59f3623dcdab6279de686a) Co-authored-by: Jason (Perry) Taylor files: M Lib/socketserver.py diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 905df9319e2fa..1ad028fa4d08c 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -24,7 +24,7 @@ The classes in this module favor the server type that is simplest to write: a synchronous TCP/IP server. This is bad class design, but -save some typing. (There's also the issue that a deep class hierarchy +saves some typing. (There's also the issue that a deep class hierarchy slows down method lookups.) There are five classes in an inheritance diagram, four of which represent From webhook-mailer at python.org Sat Nov 16 13:35:13 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 18:35:13 -0000 Subject: [Python-checkins] Fix typo in Lib/socketserver.py (GH-17024) Message-ID: https://github.com/python/cpython/commit/e7c495e32cb22a5334a75d5b0e848a8cd752717e commit: e7c495e32cb22a5334a75d5b0e848a8cd752717e branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T10:35:08-08:00 summary: Fix typo in Lib/socketserver.py (GH-17024) changed 'This is bad class design, but save some typing' into 'This is bad class design, but saves some typing'. (cherry picked from commit d0acdfcf345b44b01e59f3623dcdab6279de686a) Co-authored-by: Jason (Perry) Taylor files: M Lib/socketserver.py diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 905df9319e2fa..1ad028fa4d08c 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -24,7 +24,7 @@ The classes in this module favor the server type that is simplest to write: a synchronous TCP/IP server. This is bad class design, but -save some typing. (There's also the issue that a deep class hierarchy +saves some typing. (There's also the issue that a deep class hierarchy slows down method lookups.) There are five classes in an inheritance diagram, four of which represent From webhook-mailer at python.org Sat Nov 16 17:26:59 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 22:26:59 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) Message-ID: https://github.com/python/cpython/commit/c3f6bdc332d23588102eba749a5929dd5bb67c9d commit: c3f6bdc332d23588102eba749a5929dd5bb67c9d branch: master author: Brandt Bucher committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-16T14:26:54-08:00 summary: bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) https://bugs.python.org/issue38823 files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5e1bcfbde247c..aa46e3cf5640f 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3387,24 +3387,28 @@ PyInit__asyncio(void) Py_INCREF(&FutureType); if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { Py_DECREF(&FutureType); + Py_DECREF(m); return NULL; } Py_INCREF(&TaskType); if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { Py_DECREF(&TaskType); + Py_DECREF(m); return NULL; } Py_INCREF(all_tasks); if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { Py_DECREF(all_tasks); + Py_DECREF(m); return NULL; } Py_INCREF(current_tasks); if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { Py_DECREF(current_tasks); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sat Nov 16 17:44:31 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 22:44:31 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) Message-ID: https://github.com/python/cpython/commit/48f4f75baeee8ade1fbfab1b0aa6a21a3b13a2f2 commit: 48f4f75baeee8ade1fbfab1b0aa6a21a3b13a2f2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T14:44:15-08:00 summary: bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) https://bugs.python.org/issue38823 (cherry picked from commit c3f6bdc332d23588102eba749a5929dd5bb67c9d) Co-authored-by: Brandt Bucher files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 88b834c113322..d5f845ef0bed1 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3394,24 +3394,28 @@ PyInit__asyncio(void) Py_INCREF(&FutureType); if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { Py_DECREF(&FutureType); + Py_DECREF(m); return NULL; } Py_INCREF(&TaskType); if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { Py_DECREF(&TaskType); + Py_DECREF(m); return NULL; } Py_INCREF(all_tasks); if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { Py_DECREF(all_tasks); + Py_DECREF(m); return NULL; } Py_INCREF(current_tasks); if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { Py_DECREF(current_tasks); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sat Nov 16 17:45:29 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 22:45:29 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) Message-ID: https://github.com/python/cpython/commit/825e91be0407d6fc7fa034286b4e90634f181fab commit: 825e91be0407d6fc7fa034286b4e90634f181fab branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T14:45:24-08:00 summary: bpo-38823: Clean up refleaks in _asyncio initialization. (GH-17195) https://bugs.python.org/issue38823 (cherry picked from commit c3f6bdc332d23588102eba749a5929dd5bb67c9d) Co-authored-by: Brandt Bucher files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 62173994a6ec9..99d5f1d8596ef 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3361,24 +3361,28 @@ PyInit__asyncio(void) Py_INCREF(&FutureType); if (PyModule_AddObject(m, "Future", (PyObject *)&FutureType) < 0) { Py_DECREF(&FutureType); + Py_DECREF(m); return NULL; } Py_INCREF(&TaskType); if (PyModule_AddObject(m, "Task", (PyObject *)&TaskType) < 0) { Py_DECREF(&TaskType); + Py_DECREF(m); return NULL; } Py_INCREF(all_tasks); if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { Py_DECREF(all_tasks); + Py_DECREF(m); return NULL; } Py_INCREF(current_tasks); if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { Py_DECREF(current_tasks); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sat Nov 16 18:57:37 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 16 Nov 2019 23:57:37 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) Message-ID: https://github.com/python/cpython/commit/143a97f64128070386b12a0ee589bdaad5e51f40 commit: 143a97f64128070386b12a0ee589bdaad5e51f40 branch: master author: Brandt Bucher committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-16T15:57:32-08:00 summary: bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) https://bugs.python.org/issue38823 files: M Modules/_contextvarsmodule.c diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index 71dd7fd8d08d4..1abcdbfa921c2 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -52,6 +52,7 @@ PyInit__contextvars(void) (PyObject *)&PyContext_Type) < 0) { Py_DECREF(&PyContext_Type); + Py_DECREF(m); return NULL; } @@ -60,6 +61,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextVar_Type) < 0) { Py_DECREF(&PyContextVar_Type); + Py_DECREF(m); return NULL; } @@ -68,6 +70,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextToken_Type) < 0) { Py_DECREF(&PyContextToken_Type); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sat Nov 16 19:14:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 17 Nov 2019 00:14:52 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) Message-ID: https://github.com/python/cpython/commit/8a334af13368573cc645488481b1173d65eeeb9a commit: 8a334af13368573cc645488481b1173d65eeeb9a branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T16:14:45-08:00 summary: bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) https://bugs.python.org/issue38823 (cherry picked from commit 143a97f64128070386b12a0ee589bdaad5e51f40) Co-authored-by: Brandt Bucher files: M Modules/_contextvarsmodule.c diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index 71dd7fd8d08d4..1abcdbfa921c2 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -52,6 +52,7 @@ PyInit__contextvars(void) (PyObject *)&PyContext_Type) < 0) { Py_DECREF(&PyContext_Type); + Py_DECREF(m); return NULL; } @@ -60,6 +61,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextVar_Type) < 0) { Py_DECREF(&PyContextVar_Type); + Py_DECREF(m); return NULL; } @@ -68,6 +70,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextToken_Type) < 0) { Py_DECREF(&PyContextToken_Type); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sat Nov 16 19:16:37 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 17 Nov 2019 00:16:37 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) Message-ID: https://github.com/python/cpython/commit/1fe79a43400d092a074c6f9ae5eb290ea3e4f281 commit: 1fe79a43400d092a074c6f9ae5eb290ea3e4f281 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-16T16:16:33-08:00 summary: bpo-38823: Clean up refleaks in _contextvars initialization. (GH-17198) https://bugs.python.org/issue38823 (cherry picked from commit 143a97f64128070386b12a0ee589bdaad5e51f40) Co-authored-by: Brandt Bucher files: M Modules/_contextvarsmodule.c diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index 71dd7fd8d08d4..1abcdbfa921c2 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -52,6 +52,7 @@ PyInit__contextvars(void) (PyObject *)&PyContext_Type) < 0) { Py_DECREF(&PyContext_Type); + Py_DECREF(m); return NULL; } @@ -60,6 +61,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextVar_Type) < 0) { Py_DECREF(&PyContextVar_Type); + Py_DECREF(m); return NULL; } @@ -68,6 +70,7 @@ PyInit__contextvars(void) (PyObject *)&PyContextToken_Type) < 0) { Py_DECREF(&PyContextToken_Type); + Py_DECREF(m); return NULL; } From webhook-mailer at python.org Sun Nov 17 09:09:05 2019 From: webhook-mailer at python.org (Tal Einat) Date: Sun, 17 Nov 2019 14:09:05 -0000 Subject: [Python-checkins] bpo-38724: Implement subprocess.Popen.__repr__ (GH-17151) Message-ID: https://github.com/python/cpython/commit/645005e947c13c4a0706310a2a46112bf63cadc0 commit: 645005e947c13c4a0706310a2a46112bf63cadc0 branch: master author: Andrey Doroschenko committer: Tal Einat date: 2019-11-17T16:08:31+02:00 summary: bpo-38724: Implement subprocess.Popen.__repr__ (GH-17151) files: A Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst M Lib/subprocess.py M Lib/test/test_subprocess.py diff --git a/Lib/subprocess.py b/Lib/subprocess.py index b5a45d9fea23c..ba6f1983a5a22 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -978,6 +978,15 @@ def __init__(self, args, bufsize=-1, executable=None, raise + def __repr__(self): + obj_repr = ( + f"<{self.__class__.__name__}: " + f"returncode: {self.returncode} args: {list(self.args)!r}>" + ) + if len(obj_repr) > 80: + obj_repr = obj_repr[:76] + "...>" + return obj_repr + @property def universal_newlines(self): # universal_newlines as retained as an alias of text_mode for API diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 9e96a6d9a8747..97dc09c564965 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1360,6 +1360,30 @@ def test_communicate_epipe(self): self.addCleanup(p.stdin.close) p.communicate(b"x" * 2**20) + def test_repr(self): + # Run a command that waits for user input, to check the repr() of + # a Proc object while and after the sub-process runs. + code = 'import sys; input(); sys.exit(57)' + cmd = [sys.executable, '-c', code] + result = "') + ) + + proc.communicate(input='exit...\n') + proc.wait() + + self.assertIsNotNone(proc.returncode) + self.assertTrue( + repr(proc).startswith(result.format(proc.returncode)) and + repr(proc).endswith('>') + ) + def test_communicate_epipe_only_stdin(self): # Issue 10963: communicate() should hide EPIPE p = subprocess.Popen(ZERO_RETURN_CMD, diff --git a/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst b/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst new file mode 100644 index 0000000000000..a5ebfb3322999 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst @@ -0,0 +1 @@ +Add a repr for ``subprocess.Popen`` objects. Patch by Andrey Doroschenko. \ No newline at end of file From webhook-mailer at python.org Sun Nov 17 12:06:54 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 17 Nov 2019 17:06:54 -0000 Subject: [Python-checkins] bpo-38811: Check for presence of os.link method in pathlib. (GH-17170) Message-ID: https://github.com/python/cpython/commit/111772fc27cfe388bc060f019d68a3e33481ec65 commit: 111772fc27cfe388bc060f019d68a3e33481ec65 branch: master author: Toke H?iland-J?rgensen committer: Serhiy Storchaka date: 2019-11-17T19:06:38+02:00 summary: bpo-38811: Check for presence of os.link method in pathlib. (GH-17170) Fix also the Path.symplink() method implementation for the case when symlinks are not supported. files: A Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst M Lib/pathlib.py M Lib/test/test_pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index d70fde0ea3b45..5142ff68d100d 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -418,7 +418,12 @@ def lchmod(self, pathobj, mode): unlink = os.unlink - link_to = os.link + if hasattr(os, "link"): + link_to = os.link + else: + @staticmethod + def link_to(self, target): + raise NotImplementedError("os.link() not available on this system") rmdir = os.rmdir @@ -430,6 +435,7 @@ def lchmod(self, pathobj, mode): if supports_symlinks: symlink = os.symlink else: + @staticmethod def symlink(a, b, target_is_directory): raise NotImplementedError("symlink() not available on this system") else: diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 058a201aebc1d..d05b956be39f3 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1759,6 +1759,7 @@ def test_rmdir(self): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) + @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") def test_link_to(self): P = self.cls(BASE) p = P / 'fileA' @@ -1778,6 +1779,15 @@ def test_link_to(self): self.assertEqual(os.stat(r).st_size, size) self.assertTrue(q.stat) + @unittest.skipIf(hasattr(os, "link"), "os.link() is present") + def test_link_to_not_implemented(self): + P = self.cls(BASE) + p = P / 'fileA' + # linking to another path. + q = P / 'dirA' / 'fileAA' + with self.assertRaises(NotImplementedError): + p.link_to(q) + def test_rename(self): P = self.cls(BASE) p = P / 'fileA' @@ -2011,6 +2021,15 @@ def test_symlink_to(self): self.assertTrue(link.is_dir()) self.assertTrue(list(link.iterdir())) + @unittest.skipIf(support.can_symlink(), "symlink support is present") + def test_symlink_to_not_implemented(self): + P = self.cls(BASE) + target = P / 'fileA' + # Symlinking a path target. + link = P / 'dirA' / 'linkAA' + with self.assertRaises(NotImplementedError): + link.symlink_to(target) + def test_is_dir(self): P = self.cls(BASE) self.assertTrue((P / 'dirA').is_dir()) diff --git a/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst b/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst new file mode 100644 index 0000000000000..0e4a7f5bdf538 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst @@ -0,0 +1 @@ +Fix an unhandled exception in :mod:`pathlib` when :meth:`os.link` is missing. Patch by Toke H?iland-J?rgensen. From webhook-mailer at python.org Sun Nov 17 12:10:17 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 17 Nov 2019 17:10:17 -0000 Subject: [Python-checkins] bpo-36589: Fix the error handling in curses.update_lines_cols(). (GH-12766) Message-ID: https://github.com/python/cpython/commit/2bc343417a4de83fa6998ff91303877734ecd366 commit: 2bc343417a4de83fa6998ff91303877734ecd366 branch: master author: Zackery Spytz committer: Serhiy Storchaka date: 2019-11-17T19:10:13+02:00 summary: bpo-36589: Fix the error handling in curses.update_lines_cols(). (GH-12766) Return None instead of 1. files: A Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst M Modules/_cursesmodule.c M Modules/clinic/_cursesmodule.c.h diff --git a/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst b/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst new file mode 100644 index 0000000000000..3c1221b203494 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst @@ -0,0 +1,2 @@ +The :func:`curses.update_lines_cols` function now returns ``None`` instead +of ``1`` on success. diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 29840b52ffd81..c2ce3a968faee 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -3837,15 +3837,18 @@ update_lines_cols(void) } /*[clinic input] -_curses.update_lines_cols -> int +_curses.update_lines_cols [clinic start generated code]*/ -static int +static PyObject * _curses_update_lines_cols_impl(PyObject *module) -/*[clinic end generated code: output=0345e7f072ea711a input=3a87760f7d5197f0]*/ +/*[clinic end generated code: output=423f2b1e63ed0f75 input=5f065ab7a28a5d90]*/ { - return update_lines_cols(); + if (!update_lines_cols()) { + return NULL; + } + Py_RETURN_NONE; } #endif @@ -3929,8 +3932,10 @@ _curses_resizeterm_impl(PyObject *module, int nlines, int ncols) result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm"); if (!result) return NULL; - if (!update_lines_cols()) + if (!update_lines_cols()) { + Py_DECREF(result); return NULL; + } return result; } @@ -3966,8 +3971,10 @@ _curses_resize_term_impl(PyObject *module, int nlines, int ncols) result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term"); if (!result) return NULL; - if (!update_lines_cols()) + if (!update_lines_cols()) { + Py_DECREF(result); return NULL; + } return result; } #endif /* HAVE_CURSES_RESIZE_TERM */ @@ -4038,12 +4045,18 @@ _curses_start_color_impl(PyObject *module) c = PyLong_FromLong((long) COLORS); if (c == NULL) return NULL; - PyDict_SetItemString(ModDict, "COLORS", c); + if (PyDict_SetItemString(ModDict, "COLORS", c) < 0) { + Py_DECREF(c); + return NULL; + } Py_DECREF(c); cp = PyLong_FromLong((long) COLOR_PAIRS); if (cp == NULL) return NULL; - PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp); + if (PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp) < 0) { + Py_DECREF(cp); + return NULL; + } Py_DECREF(cp); Py_RETURN_NONE; } else { diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index 7b30a49182f9e..f3780f8e012f9 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -3921,23 +3921,13 @@ PyDoc_STRVAR(_curses_update_lines_cols__doc__, #define _CURSES_UPDATE_LINES_COLS_METHODDEF \ {"update_lines_cols", (PyCFunction)_curses_update_lines_cols, METH_NOARGS, _curses_update_lines_cols__doc__}, -static int +static PyObject * _curses_update_lines_cols_impl(PyObject *module); static PyObject * _curses_update_lines_cols(PyObject *module, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - int _return_value; - - _return_value = _curses_update_lines_cols_impl(module); - if ((_return_value == -1) && PyErr_Occurred()) { - goto exit; - } - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; + return _curses_update_lines_cols_impl(module); } #endif /* (defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)) */ @@ -4691,4 +4681,4 @@ _curses_use_default_colors(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=985c0849e841acec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0ca4f95323c5d585 input=a9049054013a1b77]*/ From webhook-mailer at python.org Sun Nov 17 17:00:50 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sun, 17 Nov 2019 22:00:50 -0000 Subject: [Python-checkins] bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) Message-ID: https://github.com/python/cpython/commit/4544e78ec4558b75bf95e5b7dfc1b5bbb07ae5f0 commit: 4544e78ec4558b75bf95e5b7dfc1b5bbb07ae5f0 branch: master author: alclarks <57201106+alclarks at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-17T14:00:43-08:00 summary: bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 2499aeb6996bb..76b7035ced979 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1566,7 +1566,7 @@ not found on a module object through the normal lookup, i.e. the module ``__dict__`` before raising an :exc:`AttributeError`. If found, it is called with the attribute name and the result is returned. -The ``__dir__`` function should accept no arguments, and return a list of +The ``__dir__`` function should accept no arguments, and return a sequence of strings that represents the names accessible on module. If present, this function overrides the standard :func:`dir` search on a module. @@ -1797,6 +1797,10 @@ Notes on using *__slots__* (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. +* If an iterator is used for *__slots__* then a descriptor is created for each + of the iterator's values. However, the *__slots__* attribute will be an empty + iterator. + .. _class-customization: Customizing class creation @@ -2128,8 +2132,8 @@ operators. It is recommended that both mappings and sequences implement the mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the :meth:`__iter__` method to allow efficient iteration -through the container; for mappings, :meth:`__iter__` should be the same as -:meth:`keys`; for sequences, it should iterate through the values. +through the container; for mappings, :meth:`__iter__` should iterate +through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) @@ -2243,9 +2247,9 @@ through the container; for mappings, :meth:`__iter__` should be the same as The membership test operators (:keyword:`in` and :keyword:`not in`) are normally -implemented as an iteration through a sequence. However, container objects can +implemented as an iteration through a container. However, container objects can supply the following special method with a more efficient implementation, which -also does not require the object be a sequence. +also does not require the object be iterable. .. method:: object.__contains__(self, item) From webhook-mailer at python.org Sun Nov 17 17:07:52 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sun, 17 Nov 2019 22:07:52 -0000 Subject: [Python-checkins] bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) (GH-17209) Message-ID: https://github.com/python/cpython/commit/72321c7be096434e3343bd5b37a4436aa9eea098 commit: 72321c7be096434e3343bd5b37a4436aa9eea098 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-17T14:07:48-08:00 summary: bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) (GH-17209) (cherry picked from commit 4544e78ec4558b75bf95e5b7dfc1b5bbb07ae5f0) Co-authored-by: alclarks <57201106+alclarks at users.noreply.github.com> files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index f5e23d85b9d86..835db9224cc74 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1563,7 +1563,7 @@ not found on a module object through the normal lookup, i.e. the module ``__dict__`` before raising an :exc:`AttributeError`. If found, it is called with the attribute name and the result is returned. -The ``__dir__`` function should accept no arguments, and return a list of +The ``__dir__`` function should accept no arguments, and return a sequence of strings that represents the names accessible on module. If present, this function overrides the standard :func:`dir` search on a module. @@ -1783,6 +1783,10 @@ Notes on using *__slots__* (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. +* If an iterator is used for *__slots__* then a descriptor is created for each + of the iterator's values. However, the *__slots__* attribute will be an empty + iterator. + .. _class-customization: Customizing class creation @@ -2115,8 +2119,8 @@ operators. It is recommended that both mappings and sequences implement the mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the :meth:`__iter__` method to allow efficient iteration -through the container; for mappings, :meth:`__iter__` should be the same as -:meth:`keys`; for sequences, it should iterate through the values. +through the container; for mappings, :meth:`__iter__` should iterate +through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) @@ -2230,9 +2234,9 @@ through the container; for mappings, :meth:`__iter__` should be the same as The membership test operators (:keyword:`in` and :keyword:`not in`) are normally -implemented as an iteration through a sequence. However, container objects can +implemented as an iteration through a container. However, container objects can supply the following special method with a more efficient implementation, which -also does not require the object be a sequence. +also does not require the object be iterable. .. method:: object.__contains__(self, item) From webhook-mailer at python.org Sun Nov 17 17:13:37 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sun, 17 Nov 2019 22:13:37 -0000 Subject: [Python-checkins] bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) (GH-17208) Message-ID: https://github.com/python/cpython/commit/20a4f6cde65549fd0252eb8c879963e0e8b40390 commit: 20a4f6cde65549fd0252eb8c879963e0e8b40390 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-17T14:13:33-08:00 summary: bpo-25866: Minor cleanups to "sequence" in docs (GH-17177) (GH-17208) (cherry picked from commit 4544e78ec4558b75bf95e5b7dfc1b5bbb07ae5f0) Co-authored-by: alclarks <57201106+alclarks at users.noreply.github.com> files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index c6c6e4075039c..1703be6e77ad9 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1566,7 +1566,7 @@ not found on a module object through the normal lookup, i.e. the module ``__dict__`` before raising an :exc:`AttributeError`. If found, it is called with the attribute name and the result is returned. -The ``__dir__`` function should accept no arguments, and return a list of +The ``__dir__`` function should accept no arguments, and return a sequence of strings that represents the names accessible on module. If present, this function overrides the standard :func:`dir` search on a module. @@ -1797,6 +1797,10 @@ Notes on using *__slots__* (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. +* If an iterator is used for *__slots__* then a descriptor is created for each + of the iterator's values. However, the *__slots__* attribute will be an empty + iterator. + .. _class-customization: Customizing class creation @@ -2128,8 +2132,8 @@ operators. It is recommended that both mappings and sequences implement the mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the :meth:`__iter__` method to allow efficient iteration -through the container; for mappings, :meth:`__iter__` should be the same as -:meth:`keys`; for sequences, it should iterate through the values. +through the container; for mappings, :meth:`__iter__` should iterate +through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) @@ -2243,9 +2247,9 @@ through the container; for mappings, :meth:`__iter__` should be the same as The membership test operators (:keyword:`in` and :keyword:`not in`) are normally -implemented as an iteration through a sequence. However, container objects can +implemented as an iteration through a container. However, container objects can supply the following special method with a more efficient implementation, which -also does not require the object be a sequence. +also does not require the object be iterable. .. method:: object.__contains__(self, item) From webhook-mailer at python.org Mon Nov 18 01:06:23 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 18 Nov 2019 06:06:23 -0000 Subject: [Python-checkins] bpo-38678: Improve argparse example in tutorial (GH-17207) Message-ID: https://github.com/python/cpython/commit/04c79d6088a22d467f04dbe438050c26de22fa85 commit: 04c79d6088a22d467f04dbe438050c26de22fa85 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-17T22:06:19-08:00 summary: bpo-38678: Improve argparse example in tutorial (GH-17207) files: M Doc/library/argparse.rst M Doc/tutorial/stdlib.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 9a1cf3a53c442..f8e3918968620 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -810,10 +810,12 @@ how the command-line arguments should be handled. The supplied actions are: example, this is useful for increasing verbosity levels:: >>> parser = argparse.ArgumentParser() - >>> parser.add_argument('--verbose', '-v', action='count') + >>> parser.add_argument('--verbose', '-v', action='count', default=0) >>> parser.parse_args(['-vvv']) Namespace(verbose=3) + Note, the *default* will be ``None`` unless explicitly set to *0*. + * ``'help'`` - This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser. See :class:`ArgumentParser` for details of how the diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index f32063e7f0960..a52653b94a325 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -72,21 +72,23 @@ three`` at the command line:: >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] -The :mod:`argparse` module provides a mechanism to process command line arguments. -It should always be preferred over directly processing ``sys.argv`` manually. - -Take, for example, the below snippet of code:: - - >>> import argparse - >>> from getpass import getuser - >>> parser = argparse.ArgumentParser(description='An argparse example.') - >>> parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.') - >>> parser.add_argument('--verbose', '-v', action='count') - >>> args = parser.parse_args() - >>> greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3] - >>> print(f'{greeting}, {args.name}') - >>> if not args.verbose: - >>> print('Try running this again with multiple "-v" flags!') +The :mod:`argparse` module provides a more sophisticated mechanism to process +command line arguments. The following script extracts one or more filenames +and an optional number of lines to be displayed:: + + import argparse + + parser = argparse.ArgumentParser(prog = 'top', + description = 'Show top lines from each file') + parser.add_argument('filenames', nargs='+') + parser.add_argument('-l', '--lines', type=int, default=10) + args = parser.parse_args() + print(args) + +When run at the command line with ``python top.py --lines=5 alpha.txt +beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames`` +to ``['alpha.txt', 'beta.txt']``. + .. _tut-stderr: From webhook-mailer at python.org Mon Nov 18 01:17:18 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 18 Nov 2019 06:17:18 -0000 Subject: [Python-checkins] bpo-38678: Improve argparse example in tutorial (GH-17207) (GH-17212) Message-ID: https://github.com/python/cpython/commit/39134b374fd506c5f0f6d232e259ba48c651d88f commit: 39134b374fd506c5f0f6d232e259ba48c651d88f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-17T22:17:14-08:00 summary: bpo-38678: Improve argparse example in tutorial (GH-17207) (GH-17212) (cherry picked from commit 04c79d6088a22d467f04dbe438050c26de22fa85) Co-authored-by: Raymond Hettinger files: M Doc/library/argparse.rst M Doc/tutorial/stdlib.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 5a61a5bf8ed90..e1b28e32ed185 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -782,10 +782,12 @@ how the command-line arguments should be handled. The supplied actions are: example, this is useful for increasing verbosity levels:: >>> parser = argparse.ArgumentParser() - >>> parser.add_argument('--verbose', '-v', action='count') + >>> parser.add_argument('--verbose', '-v', action='count', default=0) >>> parser.parse_args(['-vvv']) Namespace(verbose=3) + Note, the *default* will be ``None`` unless explicitly set to *0*. + * ``'help'`` - This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser. See :class:`ArgumentParser` for details of how the diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 20ad3563ca05e..1b89056970852 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -72,21 +72,23 @@ three`` at the command line:: >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] -The :mod:`argparse` module provides a mechanism to process command line arguments. -It should always be preferred over directly processing ``sys.argv`` manually. - -Take, for example, the below snippet of code:: - - >>> import argparse - >>> from getpass import getuser - >>> parser = argparse.ArgumentParser(description='An argparse example.') - >>> parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.') - >>> parser.add_argument('--verbose', '-v', action='count') - >>> args = parser.parse_args() - >>> greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3] - >>> print(f'{greeting}, {args.name}') - >>> if not args.verbose: - >>> print('Try running this again with multiple "-v" flags!') +The :mod:`argparse` module provides a more sophisticated mechanism to process +command line arguments. The following script extracts one or more filenames +and an optional number of lines to be displayed:: + + import argparse + + parser = argparse.ArgumentParser(prog = 'top', + description = 'Show top lines from each file') + parser.add_argument('filenames', nargs='+') + parser.add_argument('-l', '--lines', type=int, default=10) + args = parser.parse_args() + print(args) + +When run at the command line with ``python top.py --lines=5 alpha.txt +beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames`` +to ``['alpha.txt', 'beta.txt']``. + .. _tut-stderr: From webhook-mailer at python.org Mon Nov 18 01:17:54 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Mon, 18 Nov 2019 06:17:54 -0000 Subject: [Python-checkins] bpo-38678: Improve argparse example in tutorial (GH-17207) (GH-17213) Message-ID: https://github.com/python/cpython/commit/d2faac63af007e52620c642dfcc576b787b55dcd commit: d2faac63af007e52620c642dfcc576b787b55dcd branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-17T22:17:28-08:00 summary: bpo-38678: Improve argparse example in tutorial (GH-17207) (GH-17213) (cherry picked from commit 04c79d6088a22d467f04dbe438050c26de22fa85) Co-authored-by: Raymond Hettinger files: M Doc/library/argparse.rst M Doc/tutorial/stdlib.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index a2baa077cd890..4a24c267ec79f 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -778,10 +778,12 @@ how the command-line arguments should be handled. The supplied actions are: example, this is useful for increasing verbosity levels:: >>> parser = argparse.ArgumentParser() - >>> parser.add_argument('--verbose', '-v', action='count') + >>> parser.add_argument('--verbose', '-v', action='count', default=0) >>> parser.parse_args(['-vvv']) Namespace(verbose=3) + Note, the *default* will be ``None`` unless explicitly set to *0*. + * ``'help'`` - This prints a complete help message for all the options in the current parser and then exits. By default a help action is automatically added to the parser. See :class:`ArgumentParser` for details of how the diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 26f11950e79e7..a1b8c23b7bbae 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -72,21 +72,23 @@ three`` at the command line:: >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] -The :mod:`argparse` module provides a mechanism to process command line arguments. -It should always be preferred over directly processing ``sys.argv`` manually. - -Take, for example, the below snippet of code:: - - >>> import argparse - >>> from getpass import getuser - >>> parser = argparse.ArgumentParser(description='An argparse example.') - >>> parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.') - >>> parser.add_argument('--verbose', '-v', action='count') - >>> args = parser.parse_args() - >>> greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3] - >>> print(f'{greeting}, {args.name}') - >>> if not args.verbose: - >>> print('Try running this again with multiple "-v" flags!') +The :mod:`argparse` module provides a more sophisticated mechanism to process +command line arguments. The following script extracts one or more filenames +and an optional number of lines to be displayed:: + + import argparse + + parser = argparse.ArgumentParser(prog = 'top', + description = 'Show top lines from each file') + parser.add_argument('filenames', nargs='+') + parser.add_argument('-l', '--lines', type=int, default=10) + args = parser.parse_args() + print(args) + +When run at the command line with ``python top.py --lines=5 alpha.txt +beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames`` +to ``['alpha.txt', 'beta.txt']``. + .. _tut-stderr: From webhook-mailer at python.org Mon Nov 18 06:26:41 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 18 Nov 2019 11:26:41 -0000 Subject: [Python-checkins] Revert "bpo-38811: Check for presence of os.link method in pathlib. (GH-17170)" (#17219) Message-ID: https://github.com/python/cpython/commit/59c80889ff3f74230a613732aacf93d4de1e0e04 commit: 59c80889ff3f74230a613732aacf93d4de1e0e04 branch: master author: Victor Stinner committer: GitHub date: 2019-11-18T12:26:37+01:00 summary: Revert "bpo-38811: Check for presence of os.link method in pathlib. (GH-17170)" (#17219) This reverts commit 111772fc27cfe388bc060f019d68a3e33481ec65. files: D Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst M Lib/pathlib.py M Lib/test/test_pathlib.py diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 5142ff68d100d..d70fde0ea3b45 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -418,12 +418,7 @@ def lchmod(self, pathobj, mode): unlink = os.unlink - if hasattr(os, "link"): - link_to = os.link - else: - @staticmethod - def link_to(self, target): - raise NotImplementedError("os.link() not available on this system") + link_to = os.link rmdir = os.rmdir @@ -435,7 +430,6 @@ def link_to(self, target): if supports_symlinks: symlink = os.symlink else: - @staticmethod def symlink(a, b, target_is_directory): raise NotImplementedError("symlink() not available on this system") else: diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index d05b956be39f3..058a201aebc1d 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1759,7 +1759,6 @@ def test_rmdir(self): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) - @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") def test_link_to(self): P = self.cls(BASE) p = P / 'fileA' @@ -1779,15 +1778,6 @@ def test_link_to(self): self.assertEqual(os.stat(r).st_size, size) self.assertTrue(q.stat) - @unittest.skipIf(hasattr(os, "link"), "os.link() is present") - def test_link_to_not_implemented(self): - P = self.cls(BASE) - p = P / 'fileA' - # linking to another path. - q = P / 'dirA' / 'fileAA' - with self.assertRaises(NotImplementedError): - p.link_to(q) - def test_rename(self): P = self.cls(BASE) p = P / 'fileA' @@ -2021,15 +2011,6 @@ def test_symlink_to(self): self.assertTrue(link.is_dir()) self.assertTrue(list(link.iterdir())) - @unittest.skipIf(support.can_symlink(), "symlink support is present") - def test_symlink_to_not_implemented(self): - P = self.cls(BASE) - target = P / 'fileA' - # Symlinking a path target. - link = P / 'dirA' / 'linkAA' - with self.assertRaises(NotImplementedError): - link.symlink_to(target) - def test_is_dir(self): P = self.cls(BASE) self.assertTrue((P / 'dirA').is_dir()) diff --git a/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst b/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst deleted file mode 100644 index 0e4a7f5bdf538..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-15-18-06-04.bpo-38811.AmdQ6M.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an unhandled exception in :mod:`pathlib` when :meth:`os.link` is missing. Patch by Toke H?iland-J?rgensen. From webhook-mailer at python.org Mon Nov 18 07:03:26 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Mon, 18 Nov 2019 12:03:26 -0000 Subject: [Python-checkins] bpo-38830: Correct slot signature in Qt example. (GH-17220) Message-ID: https://github.com/python/cpython/commit/5383956583bb758f3828513bcdd011871f24a0e8 commit: 5383956583bb758f3828513bcdd011871f24a0e8 branch: master author: Vinay Sajip committer: GitHub date: 2019-11-18T12:03:22Z summary: bpo-38830: Correct slot signature in Qt example. (GH-17220) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 9f52780af4fc2..17f4ff6e474c2 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2949,7 +2949,7 @@ refer to the comments in the code snippet for more detailed information. # The functions below update the UI and run in the main thread because # that's where the slots are set up - @Slot(str) + @Slot(str, logging.LogRecord) def update_status(self, status, record): color = self.COLORS.get(record.levelno, 'black') s = '
%s
' % (color, status) From webhook-mailer at python.org Mon Nov 18 07:23:53 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Mon, 18 Nov 2019 12:23:53 -0000 Subject: [Python-checkins] [3.8] bpo-38830: Correct slot signature in Qt example. (GH-17220) (GH-17221) Message-ID: https://github.com/python/cpython/commit/21eb731057d614fb642c609ae89f66d75fa0ac3a commit: 21eb731057d614fb642c609ae89f66d75fa0ac3a branch: 3.8 author: Vinay Sajip committer: GitHub date: 2019-11-18T12:23:46Z summary: [3.8] bpo-38830: Correct slot signature in Qt example. (GH-17220) (GH-17221) (cherry picked from commit 5383956583bb758f3828513bcdd011871f24a0e8) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 9f52780af4fc2..17f4ff6e474c2 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2949,7 +2949,7 @@ refer to the comments in the code snippet for more detailed information. # The functions below update the UI and run in the main thread because # that's where the slots are set up - @Slot(str) + @Slot(str, logging.LogRecord) def update_status(self, status, record): color = self.COLORS.get(record.levelno, 'black') s = '
%s
' % (color, status) From webhook-mailer at python.org Mon Nov 18 07:24:20 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Mon, 18 Nov 2019 12:24:20 -0000 Subject: [Python-checkins] [3.7] bpo-38830: Correct slot signature in Qt example. (GH-17220) (GH-17222) Message-ID: https://github.com/python/cpython/commit/9a4c5c30d93278e420a7dadafbaa35a5b52325ec commit: 9a4c5c30d93278e420a7dadafbaa35a5b52325ec branch: 3.7 author: Vinay Sajip committer: GitHub date: 2019-11-18T12:24:16Z summary: [3.7] bpo-38830: Correct slot signature in Qt example. (GH-17220) (GH-17222) (cherry picked from commit 5383956583bb758f3828513bcdd011871f24a0e8) files: M Doc/howto/logging-cookbook.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index a9222ab6ce38e..6ab1e39f0652b 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -2584,3 +2584,399 @@ In this case, the message #5 printed to ``stdout`` doesn't appear, as expected. Of course, the approach described here can be generalised, for example to attach logging filters temporarily. Note that the above code works in Python 2 as well as Python 3. + + +.. _starter-template: + +A CLI application starter template +---------------------------------- + +Here's an example which shows how you can: + +* Use a logging level based on command-line arguments +* Dispatch to multiple subcommands in separate files, all logging at the same + level in a consistent way +* Make use of simple, minimal configuration + +Suppose we have a command-line application whose job is to stop, start or +restart some services. This could be organised for the purposes of illustration +as a file ``app.py`` that is the main script for the application, with individual +commands implemented in ``start.py``, ``stop.py`` and ``restart.py``. Suppose +further that we want to control the verbosity of the application via a +command-line argument, defaulting to ``logging.INFO``. Here's one way that +``app.py`` could be written:: + + import argparse + import importlib + import logging + import os + import sys + + def main(args=None): + scriptname = os.path.basename(__file__) + parser = argparse.ArgumentParser(scriptname) + levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') + parser.add_argument('--log-level', default='INFO', choices=levels) + subparsers = parser.add_subparsers(dest='command', + help='Available commands:') + start_cmd = subparsers.add_parser('start', help='Start a service') + start_cmd.add_argument('name', metavar='NAME', + help='Name of service to start') + stop_cmd = subparsers.add_parser('stop', + help='Stop one or more services') + stop_cmd.add_argument('names', metavar='NAME', nargs='+', + help='Name of service to stop') + restart_cmd = subparsers.add_parser('restart', + help='Restart one or more services') + restart_cmd.add_argument('names', metavar='NAME', nargs='+', + help='Name of service to restart') + options = parser.parse_args() + # the code to dispatch commands could all be in this file. For the purposes + # of illustration only, we implement each command in a separate module. + try: + mod = importlib.import_module(options.command) + cmd = getattr(mod, 'command') + except (ImportError, AttributeError): + print('Unable to find the code for command \'%s\'' % options.command) + return 1 + # Could get fancy here and load configuration from file or dictionary + logging.basicConfig(level=options.log_level, + format='%(levelname)s %(name)s %(message)s') + cmd(options) + + if __name__ == '__main__': + sys.exit(main()) + +And the ``start``, ``stop`` and ``restart`` commands can be implemented in +separate modules, like so for starting:: + + # start.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + logger.debug('About to start %s', options.name) + # actually do the command processing here ... + logger.info('Started the \'%s\' service.', options.name) + +and thus for stopping:: + + # stop.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + n = len(options.names) + if n == 1: + plural = '' + services = '\'%s\'' % options.names[0] + else: + plural = 's' + services = ', '.join('\'%s\'' % name for name in options.names) + i = services.rfind(', ') + services = services[:i] + ' and ' + services[i + 2:] + logger.debug('About to stop %s', services) + # actually do the command processing here ... + logger.info('Stopped the %s service%s.', services, plural) + +and similarly for restarting:: + + # restart.py + import logging + + logger = logging.getLogger(__name__) + + def command(options): + n = len(options.names) + if n == 1: + plural = '' + services = '\'%s\'' % options.names[0] + else: + plural = 's' + services = ', '.join('\'%s\'' % name for name in options.names) + i = services.rfind(', ') + services = services[:i] + ' and ' + services[i + 2:] + logger.debug('About to restart %s', services) + # actually do the command processing here ... + logger.info('Restarted the %s service%s.', services, plural) + +If we run this application with the default log level, we get output like this: + +.. code-block:: shell-session + + $ python app.py start foo + INFO start Started the 'foo' service. + + $ python app.py stop foo bar + INFO stop Stopped the 'foo' and 'bar' services. + + $ python app.py restart foo bar baz + INFO restart Restarted the 'foo', 'bar' and 'baz' services. + +The first word is the logging level, and the second word is the module or +package name of the place where the event was logged. + +If we change the logging level, then we can change the information sent to the +log. For example, if we want more information: + +.. code-block:: shell-session + + $ python app.py --log-level DEBUG start foo + DEBUG start About to start foo + INFO start Started the 'foo' service. + + $ python app.py --log-level DEBUG stop foo bar + DEBUG stop About to stop 'foo' and 'bar' + INFO stop Stopped the 'foo' and 'bar' services. + + $ python app.py --log-level DEBUG restart foo bar baz + DEBUG restart About to restart 'foo', 'bar' and 'baz' + INFO restart Restarted the 'foo', 'bar' and 'baz' services. + +And if we want less: + +.. code-block:: shell-session + + $ python app.py --log-level WARNING start foo + $ python app.py --log-level WARNING stop foo bar + $ python app.py --log-level WARNING restart foo bar baz + +In this case, the commands don't print anything to the console, since nothing +at ``WARNING`` level or above is logged by them. + +.. _qt-gui: + +A Qt GUI for logging +-------------------- + +A question that comes up from time to time is about how to log to a GUI +application. The `Qt `_ framework is a popular +cross-platform UI framework with Python bindings using `PySide2 +`_ or `PyQt5 +`_ libraries. + +The following example shows how to log to a Qt GUI. This introduces a simple +``QtHandler`` class which takes a callable, which should be a slot in the main +thread that does GUI updates. A worker thread is also created to show how you +can log to the GUI from both the UI itself (via a button for manual logging) +as well as a worker thread doing work in the background (here, just logging +messages at random levels with random short delays in between). + +The worker thread is implemented using Qt's ``QThread`` class rather than the +:mod:`threading` module, as there are circumstances where one has to use +``QThread``, which offers better integration with other ``Qt`` components. + +The code should work with recent releases of either ``PySide2`` or ``PyQt5``. +You should be able to adapt the approach to earlier versions of Qt. Please +refer to the comments in the code snippet for more detailed information. + +.. code-block:: python3 + + import datetime + import logging + import random + import sys + import time + + # Deal with minor differences between PySide2 and PyQt5 + try: + from PySide2 import QtCore, QtGui, QtWidgets + Signal = QtCore.Signal + Slot = QtCore.Slot + except ImportError: + from PyQt5 import QtCore, QtGui, QtWidgets + Signal = QtCore.pyqtSignal + Slot = QtCore.pyqtSlot + + + logger = logging.getLogger(__name__) + + + # + # Signals need to be contained in a QObject or subclass in order to be correctly + # initialized. + # + class Signaller(QtCore.QObject): + signal = Signal(str, logging.LogRecord) + + # + # Output to a Qt GUI is only supposed to happen on the main thread. So, this + # handler is designed to take a slot function which is set up to run in the main + # thread. In this example, the function takes a string argument which is a + # formatted log message, and the log record which generated it. The formatted + # string is just a convenience - you could format a string for output any way + # you like in the slot function itself. + # + # You specify the slot function to do whatever GUI updates you want. The handler + # doesn't know or care about specific UI elements. + # + class QtHandler(logging.Handler): + def __init__(self, slotfunc, *args, **kwargs): + super(QtHandler, self).__init__(*args, **kwargs) + self.signaller = Signaller() + self.signaller.signal.connect(slotfunc) + + def emit(self, record): + s = self.format(record) + self.signaller.signal.emit(s, record) + + # + # This example uses QThreads, which means that the threads at the Python level + # are named something like "Dummy-1". The function below gets the Qt name of the + # current thread. + # + def ctname(): + return QtCore.QThread.currentThread().objectName() + + + # + # Used to generate random levels for logging. + # + LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, + logging.CRITICAL) + + # + # This worker class represents work that is done in a thread separate to the + # main thread. The way the thread is kicked off to do work is via a button press + # that connects to a slot in the worker. + # + # Because the default threadName value in the LogRecord isn't much use, we add + # a qThreadName which contains the QThread name as computed above, and pass that + # value in an "extra" dictionary which is used to update the LogRecord with the + # QThread name. + # + # This example worker just outputs messages sequentially, interspersed with + # random delays of the order of a few seconds. + # + class Worker(QtCore.QObject): + @Slot() + def start(self): + extra = {'qThreadName': ctname() } + logger.debug('Started work', extra=extra) + i = 1 + # Let the thread run until interrupted. This allows reasonably clean + # thread termination. + while not QtCore.QThread.currentThread().isInterruptionRequested(): + delay = 0.5 + random.random() * 2 + time.sleep(delay) + level = random.choice(LEVELS) + logger.log(level, 'Message after delay of %3.1f: %d', delay, i, extra=extra) + i += 1 + + # + # Implement a simple UI for this cookbook example. This contains: + # + # * A read-only text edit window which holds formatted log messages + # * A button to start work and log stuff in a separate thread + # * A button to log something from the main thread + # * A button to clear the log window + # + class Window(QtWidgets.QWidget): + + COLORS = { + logging.DEBUG: 'black', + logging.INFO: 'blue', + logging.WARNING: 'orange', + logging.ERROR: 'red', + logging.CRITICAL: 'purple', + } + + def __init__(self, app): + super(Window, self).__init__() + self.app = app + self.textedit = te = QtWidgets.QPlainTextEdit(self) + # Set whatever the default monospace font is for the platform + f = QtGui.QFont('nosuchfont') + f.setStyleHint(f.Monospace) + te.setFont(f) + te.setReadOnly(True) + PB = QtWidgets.QPushButton + self.work_button = PB('Start background work', self) + self.log_button = PB('Log a message at a random level', self) + self.clear_button = PB('Clear log window', self) + self.handler = h = QtHandler(self.update_status) + # Remember to use qThreadName rather than threadName in the format string. + fs = '%(asctime)s %(qThreadName)-12s %(levelname)-8s %(message)s' + formatter = logging.Formatter(fs) + h.setFormatter(formatter) + logger.addHandler(h) + # Set up to terminate the QThread when we exit + app.aboutToQuit.connect(self.force_quit) + + # Lay out all the widgets + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(te) + layout.addWidget(self.work_button) + layout.addWidget(self.log_button) + layout.addWidget(self.clear_button) + self.setFixedSize(900, 400) + + # Connect the non-worker slots and signals + self.log_button.clicked.connect(self.manual_update) + self.clear_button.clicked.connect(self.clear_display) + + # Start a new worker thread and connect the slots for the worker + self.start_thread() + self.work_button.clicked.connect(self.worker.start) + # Once started, the button should be disabled + self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False)) + + def start_thread(self): + self.worker = Worker() + self.worker_thread = QtCore.QThread() + self.worker.setObjectName('Worker') + self.worker_thread.setObjectName('WorkerThread') # for qThreadName + self.worker.moveToThread(self.worker_thread) + # This will start an event loop in the worker thread + self.worker_thread.start() + + def kill_thread(self): + # Just tell the worker to stop, then tell it to quit and wait for that + # to happen + self.worker_thread.requestInterruption() + if self.worker_thread.isRunning(): + self.worker_thread.quit() + self.worker_thread.wait() + else: + print('worker has already exited.') + + def force_quit(self): + # For use when the window is closed + if self.worker_thread.isRunning(): + self.kill_thread() + + # The functions below update the UI and run in the main thread because + # that's where the slots are set up + + @Slot(str, logging.LogRecord) + def update_status(self, status, record): + color = self.COLORS.get(record.levelno, 'black') + s = '
%s
' % (color, status) + self.textedit.appendHtml(s) + + @Slot() + def manual_update(self): + # This function uses the formatted message passed in, but also uses + # information from the record to format the message in an appropriate + # color according to its severity (level). + level = random.choice(LEVELS) + extra = {'qThreadName': ctname() } + logger.log(level, 'Manually logged!', extra=extra) + + @Slot() + def clear_display(self): + self.textedit.clear() + + + def main(): + QtCore.QThread.currentThread().setObjectName('MainThread') + logging.getLogger().setLevel(logging.DEBUG) + app = QtWidgets.QApplication(sys.argv) + example = Window(app) + example.show() + sys.exit(app.exec_()) + + if __name__=='__main__': + main() From webhook-mailer at python.org Mon Nov 18 09:29:22 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Mon, 18 Nov 2019 14:29:22 -0000 Subject: [Python-checkins] bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) (GH-17223) Message-ID: https://github.com/python/cpython/commit/bef2815533011be9f0ce5fa2965bcada76b509b8 commit: bef2815533011be9f0ce5fa2965bcada76b509b8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Vinay Sajip date: 2019-11-18T14:29:15Z summary: bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) (GH-17223) (cherry picked from commit 106271568c58cfebae58f0c52b640dbe716ba2ce) files: M Lib/ctypes/test/test_structures.py M Modules/_ctypes/_ctypes.c M Modules/_ctypes/_ctypes_test.c diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 8541674066546..19c4430bea344 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -651,6 +651,87 @@ class Test5(Structure): self.assertEqual(test5.nested.an_int, 0) self.assertEqual(test5.another_int, 0) + #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390') + def test_bitfield_by_value(self): + # See bpo-16576 + + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c + + class Test6(Structure): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test6 = Test6() + # As these are signed int fields, all are logically -1 due to sign + # extension. + test6.A = 1 + test6.B = 3 + test6.C = 7 + test6.D = 3 + dll = CDLL(_ctypes_test.__file__) + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value1 + func.restype = c_long + func.argtypes = (Test6,) + result = func(test6) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a struct/union with a bitfield by value, which is ' + 'unsupported.') + # passing by reference should be OK + func = dll._testfunc_bitfield_by_reference1 + func.restype = c_long + func.argtypes = (POINTER(Test6),) + result = func(byref(test6)) + self.assertEqual(result, -4) + self.assertEqual(test6.A, 0) + self.assertEqual(test6.B, 0) + self.assertEqual(test6.C, 0) + self.assertEqual(test6.D, 0) + + class Test7(Structure): + _fields_ = [ + ('A', c_uint, 1), + ('B', c_uint, 2), + ('C', c_uint, 3), + ('D', c_uint, 2), + ] + test7 = Test7() + test7.A = 1 + test7.B = 3 + test7.C = 7 + test7.D = 3 + func = dll._testfunc_bitfield_by_reference2 + func.restype = c_long + func.argtypes = (POINTER(Test7),) + result = func(byref(test7)) + self.assertEqual(result, 14) + self.assertEqual(test7.A, 0) + self.assertEqual(test7.B, 0) + self.assertEqual(test7.C, 0) + self.assertEqual(test7.D, 0) + + # for a union with bitfields, the union check happens first + class Test8(Union): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test8 = Test8() + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value2 + func.restype = c_long + func.argtypes = (Test8,) + result = func(test8) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index a2fddda87a53e..13f9f212236ed 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2400,11 +2400,18 @@ converters_from_argtypes(PyObject *ob) } return NULL; } - /* if (stgdict->flags & TYPEFLAG_HASBITFIELD) { - printf("found stgdict with bitfield\n"); + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a struct/" + "union with a bitfield by value, which is " + "unsupported.", + i + 1); + } + return NULL; } - */ } if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 223be850a6d73..33922082ab11a 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -198,6 +198,56 @@ _testfunc_union_by_reference3(Test5 *in) { return result; } +typedef struct { + signed int A: 1, B:2, C:3, D:2; +} Test6; + +EXPORT(long) +_testfunc_bitfield_by_value1(Test6 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_bitfield_by_reference1(Test6 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test6)); + return result; +} + +typedef struct { + unsigned int A: 1, B:2, C:3, D:2; +} Test7; + +EXPORT(long) +_testfunc_bitfield_by_reference2(Test7 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test7)); + return result; +} + +typedef union { + signed int A: 1, B:2, C:3, D:2; +} Test8; + +EXPORT(long) +_testfunc_bitfield_by_value2(Test8 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", From webhook-mailer at python.org Mon Nov 18 09:52:48 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 14:52:48 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) Message-ID: https://github.com/python/cpython/commit/289cf0fbf78c4f38c38ac71ac8b772be7ec2672f commit: 289cf0fbf78c4f38c38ac71ac8b772be7ec2672f branch: master author: Brandt Bucher committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-18T06:52:36-08:00 summary: bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) https://bugs.python.org/issue38823 files: M Modules/_tkinter.c diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 235cb6bc28dd5..40d2ed7f88b11 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3555,11 +3555,13 @@ PyInit__tkinter(void) if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { str_path = _get_tcl_lib_path(); if (str_path == NULL && PyErr_Occurred()) { + Py_DECREF(m); return NULL; } if (str_path != NULL) { wcs_path = PyUnicode_AsWideCharString(str_path, NULL); if (wcs_path == NULL) { + Py_DECREF(m); return NULL; } SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); From webhook-mailer at python.org Mon Nov 18 10:09:52 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 15:09:52 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) Message-ID: https://github.com/python/cpython/commit/9e4d0312101cc2bc44a9549974d4a25f80e1dc12 commit: 9e4d0312101cc2bc44a9549974d4a25f80e1dc12 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T07:09:43-08:00 summary: bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) https://bugs.python.org/issue38823 (cherry picked from commit 289cf0fbf78c4f38c38ac71ac8b772be7ec2672f) Co-authored-by: Brandt Bucher files: M Modules/_tkinter.c diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 8ea302ea639f9..bc648dc074668 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3552,11 +3552,13 @@ PyInit__tkinter(void) if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { str_path = _get_tcl_lib_path(); if (str_path == NULL && PyErr_Occurred()) { + Py_DECREF(m); return NULL; } if (str_path != NULL) { wcs_path = PyUnicode_AsWideCharString(str_path, NULL); if (wcs_path == NULL) { + Py_DECREF(m); return NULL; } SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); From webhook-mailer at python.org Mon Nov 18 10:10:35 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 15:10:35 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) Message-ID: https://github.com/python/cpython/commit/42a4359390b78b3360e100fc9c075495e48354b2 commit: 42a4359390b78b3360e100fc9c075495e48354b2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T07:10:31-08:00 summary: bpo-38823: Clean up refleaks in _tkinter initialization. (GH-17206) https://bugs.python.org/issue38823 (cherry picked from commit 289cf0fbf78c4f38c38ac71ac8b772be7ec2672f) Co-authored-by: Brandt Bucher files: M Modules/_tkinter.c diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index b622c158a48fa..a1071e5a5812f 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3549,11 +3549,13 @@ PyInit__tkinter(void) if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { str_path = _get_tcl_lib_path(); if (str_path == NULL && PyErr_Occurred()) { + Py_DECREF(m); return NULL; } if (str_path != NULL) { wcs_path = PyUnicode_AsWideCharString(str_path, NULL); if (wcs_path == NULL) { + Py_DECREF(m); return NULL; } SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); From webhook-mailer at python.org Mon Nov 18 10:30:57 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 15:30:57 -0000 Subject: [Python-checkins] Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) Message-ID: https://github.com/python/cpython/commit/f49f6baa6bf7916ac039194c24b59d2eff5b180a commit: f49f6baa6bf7916ac039194c24b59d2eff5b180a branch: master author: ????? ???????? committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-18T07:30:53-08:00 summary: Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) `~` is now treated as an unreserved character (i.e. it doesn't get quoted), not a reserved one. files: M Doc/library/urllib.parse.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 84d289bc4415c..2d4d5a9e60969 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -529,7 +529,7 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.7 Moved from :rfc:`2396` to :rfc:`3986` for quoting URL strings. "~" is now - included in the set of reserved characters. + included in the set of unreserved characters. The optional *encoding* and *errors* parameters specify how to deal with non-ASCII characters, as accepted by the :meth:`str.encode` method. From webhook-mailer at python.org Mon Nov 18 10:42:22 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 15:42:22 -0000 Subject: [Python-checkins] Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) Message-ID: https://github.com/python/cpython/commit/ca877c7523b103e1cf5815d866ce66a13ecca6a2 commit: ca877c7523b103e1cf5815d866ce66a13ecca6a2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T07:42:13-08:00 summary: Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) `~` is now treated as an unreserved character (i.e. it doesn't get quoted), not a reserved one. (cherry picked from commit f49f6baa6bf7916ac039194c24b59d2eff5b180a) Co-authored-by: ????? ???????? files: M Doc/library/urllib.parse.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 49276daa7ff43..52f98ef39fcc3 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -529,7 +529,7 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.7 Moved from :rfc:`2396` to :rfc:`3986` for quoting URL strings. "~" is now - included in the set of reserved characters. + included in the set of unreserved characters. The optional *encoding* and *errors* parameters specify how to deal with non-ASCII characters, as accepted by the :meth:`str.encode` method. From webhook-mailer at python.org Mon Nov 18 10:42:25 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 15:42:25 -0000 Subject: [Python-checkins] Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) Message-ID: https://github.com/python/cpython/commit/3f4e7f7eb342daa41922d00366827b0a1b233bf7 commit: 3f4e7f7eb342daa41922d00366827b0a1b233bf7 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T07:42:20-08:00 summary: Correct the description of the 3.7 change in urllib.parse.quote (GH-17065) `~` is now treated as an unreserved character (i.e. it doesn't get quoted), not a reserved one. (cherry picked from commit f49f6baa6bf7916ac039194c24b59d2eff5b180a) Co-authored-by: ????? ???????? files: M Doc/library/urllib.parse.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index ddc3ee23f48a7..f499412144008 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -520,7 +520,7 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.7 Moved from :rfc:`2396` to :rfc:`3986` for quoting URL strings. "~" is now - included in the set of reserved characters. + included in the set of unreserved characters. The optional *encoding* and *errors* parameters specify how to deal with non-ASCII characters, as accepted by the :meth:`str.encode` method. From webhook-mailer at python.org Mon Nov 18 11:39:52 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 18 Nov 2019 16:39:52 -0000 Subject: [Python-checkins] bpo-38631: Avoid Py_FatalError() in float.__getformat__() (GH-17232) Message-ID: https://github.com/python/cpython/commit/04394df74b3d0783893da7dafa7803a003516402 commit: 04394df74b3d0783893da7dafa7803a003516402 branch: master author: Victor Stinner committer: GitHub date: 2019-11-18T17:39:48+01:00 summary: bpo-38631: Avoid Py_FatalError() in float.__getformat__() (GH-17232) Replace Py_FatalError() with a regular RuntimeError exception in float.__getformat__(). files: A Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk.rst M Objects/floatobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk.rst new file mode 100644 index 0000000000000..d05ad05941ecf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk.rst @@ -0,0 +1,2 @@ +Replace ``Py_FatalError()`` call with a regular :exc:`RuntimeError` +exception in :meth:`float.__getformat__`. diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 8c08866d73725..3f9bbde2abe03 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1726,7 +1726,8 @@ float___getformat___impl(PyTypeObject *type, const char *typestr) case ieee_big_endian_format: return PyUnicode_FromString("IEEE, big-endian"); default: - Py_FatalError("insane float_format or double_format"); + PyErr_SetString(PyExc_RuntimeError, + "insane float_format or double_format"); return NULL; } } From webhook-mailer at python.org Mon Nov 18 11:40:12 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Mon, 18 Nov 2019 16:40:12 -0000 Subject: [Python-checkins] bpo-38631: Avoid Py_FatalError() in _multibytecodec init (GH-17233) Message-ID: https://github.com/python/cpython/commit/bc7d3aa6d74b718699b7a6bced9b0dfdfbf95c13 commit: bc7d3aa6d74b718699b7a6bced9b0dfdfbf95c13 branch: master author: Victor Stinner committer: GitHub date: 2019-11-18T17:40:07+01:00 summary: bpo-38631: Avoid Py_FatalError() in _multibytecodec init (GH-17233) If an exception is raised and PyInit__multibytecodec() returns NULL, Python reports properly the exception to the user. There is no need to crash Python with Py_FatalError(). files: M Modules/cjkcodecs/multibytecodec.c diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 56d007607e218..f24ec933508f1 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -2085,7 +2085,6 @@ PyInit__multibytecodec(void) } if (PyErr_Occurred()) { - Py_FatalError("can't initialize the _multibytecodec module"); Py_DECREF(m); m = NULL; } From webhook-mailer at python.org Mon Nov 18 12:32:36 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 17:32:36 -0000 Subject: [Python-checkins] bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) Message-ID: https://github.com/python/cpython/commit/ee703cbb418b7458bebb1d26a5e19d6b55280b28 commit: ee703cbb418b7458bebb1d26a5e19d6b55280b28 branch: master author: Tal Einat committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-18T09:32:25-08:00 summary: bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) https://bugs.python.org/issue38809 files: A Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst M PCbuild/find_python.bat diff --git a/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst new file mode 100644 index 0000000000000..10eaf844e8aaf --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst @@ -0,0 +1,2 @@ +On Windows, build scripts will now recognize and use python.exe from an +active virtual env. diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index d5c787fd77aa4..40937a67c33ac 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -24,6 +24,9 @@ :begin_search @set PYTHON= + at rem If there is an active virtual env, use that one + at if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found + @set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% @if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals) From webhook-mailer at python.org Mon Nov 18 12:53:18 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 17:53:18 -0000 Subject: [Python-checkins] bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) Message-ID: https://github.com/python/cpython/commit/2b928d9bf75d82b86dc3b4fcbc243d36a7958f4c commit: 2b928d9bf75d82b86dc3b4fcbc243d36a7958f4c branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T09:53:14-08:00 summary: bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) https://bugs.python.org/issue38809 (cherry picked from commit ee703cbb418b7458bebb1d26a5e19d6b55280b28) Co-authored-by: Tal Einat files: A Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst M PCbuild/find_python.bat diff --git a/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst new file mode 100644 index 0000000000000..10eaf844e8aaf --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst @@ -0,0 +1,2 @@ +On Windows, build scripts will now recognize and use python.exe from an +active virtual env. diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index d5c787fd77aa4..40937a67c33ac 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -24,6 +24,9 @@ :begin_search @set PYTHON= + at rem If there is an active virtual env, use that one + at if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found + @set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% @if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals) From webhook-mailer at python.org Mon Nov 18 12:53:25 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 17:53:25 -0000 Subject: [Python-checkins] bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) Message-ID: https://github.com/python/cpython/commit/cbbf1098f383e575d93841e555329eb66283c2f1 commit: cbbf1098f383e575d93841e555329eb66283c2f1 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T09:53:21-08:00 summary: bpo-38809: Windows build scripts use python.exe from virtual envs (GH-17164) https://bugs.python.org/issue38809 (cherry picked from commit ee703cbb418b7458bebb1d26a5e19d6b55280b28) Co-authored-by: Tal Einat files: A Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst M PCbuild/find_python.bat diff --git a/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst new file mode 100644 index 0000000000000..10eaf844e8aaf --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst @@ -0,0 +1,2 @@ +On Windows, build scripts will now recognize and use python.exe from an +active virtual env. diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index d5c787fd77aa4..40937a67c33ac 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -24,6 +24,9 @@ :begin_search @set PYTHON= + at rem If there is an active virtual env, use that one + at if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found + @set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% @if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%~dp0\..\externals) From webhook-mailer at python.org Mon Nov 18 13:39:55 2019 From: webhook-mailer at python.org (Tal Einat) Date: Mon, 18 Nov 2019 18:39:55 -0000 Subject: [Python-checkins] remove a strange non-ASCII character in _iomodule.c (GH-17239) Message-ID: https://github.com/python/cpython/commit/bcc1cc5cc38b57ac55cbe710849374258d610a08 commit: bcc1cc5cc38b57ac55cbe710849374258d610a08 branch: master author: Tal Einat committer: GitHub date: 2019-11-18T20:39:47+02:00 summary: remove a strange non-ASCII character in _iomodule.c (GH-17239) files: M Modules/_io/_iomodule.c diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 5932363f3af35..778b56d475ee5 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -503,7 +503,7 @@ _io_open_code_impl(PyObject *module, PyObject *path) { return PyFile_OpenCodeObject(path); } - + /* * Private helpers for the io module. */ From webhook-mailer at python.org Mon Nov 18 14:11:22 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 19:11:22 -0000 Subject: [Python-checkins] bpo-38722: Runpy use io.open_code() (GH-17234) Message-ID: https://github.com/python/cpython/commit/e243bae9999418859106328d9fce71815b7eb2fe commit: e243bae9999418859106328d9fce71815b7eb2fe branch: master author: jsnklln committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-18T11:11:13-08:00 summary: bpo-38722: Runpy use io.open_code() (GH-17234) https://bugs.python.org/issue38722 Automerge-Triggered-By: @taleinat files: A Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst M Lib/runpy.py diff --git a/Lib/runpy.py b/Lib/runpy.py index d86f0e4a3c49b..8adc91e32f319 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -13,6 +13,7 @@ import sys import importlib.machinery # importlib first so we can test #15386 via -m import importlib.util +import io import types from pkgutil import read_code, get_importer @@ -228,11 +229,11 @@ def _get_main_module_details(error=ImportError): def _get_code_from_file(run_name, fname): # Check for a compiled file first - with open(fname, "rb") as f: + with io.open_code(fname) as f: code = read_code(f) if code is None: # That didn't work, so try it as normal source code - with open(fname, "rb") as f: + with io.open_code(fname) as f: code = compile(f.read(), fname, 'exec') return code, fname diff --git a/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst b/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst new file mode 100644 index 0000000000000..0277d3e5689a2 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst @@ -0,0 +1,2 @@ +:mod:`runpy` now uses :meth:`io.open_code` to open code files. +Patch by Jason Killen. From webhook-mailer at python.org Mon Nov 18 14:19:55 2019 From: webhook-mailer at python.org (Tal Einat) Date: Mon, 18 Nov 2019 19:19:55 -0000 Subject: [Python-checkins] Revert "remove a strange non-ASCII character in _iomodule.c" (GH-17240) Message-ID: https://github.com/python/cpython/commit/476e76f7cf78598146140c3bda48d53cda50707c commit: 476e76f7cf78598146140c3bda48d53cda50707c branch: master author: Tal Einat committer: GitHub date: 2019-11-18T21:19:51+02:00 summary: Revert "remove a strange non-ASCII character in _iomodule.c" (GH-17240) This reverts commit bcc1cc5c, which removed an intentionally placed "form feed" character. files: M Modules/_io/_iomodule.c diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 778b56d475ee5..5932363f3af35 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -503,7 +503,7 @@ _io_open_code_impl(PyObject *module, PyObject *path) { return PyFile_OpenCodeObject(path); } - + /* * Private helpers for the io module. */ From webhook-mailer at python.org Mon Nov 18 14:32:50 2019 From: webhook-mailer at python.org (Steve Dower) Date: Mon, 18 Nov 2019 19:32:50 -0000 Subject: [Python-checkins] bpo-38622: Add missing audit events for ctypes module (GH-17158) Message-ID: https://github.com/python/cpython/commit/00923c63995e34cdc25d699478f113de99a69df9 commit: 00923c63995e34cdc25d699478f113de99a69df9 branch: master author: Steve Dower committer: GitHub date: 2019-11-18T11:32:46-08:00 summary: bpo-38622: Add missing audit events for ctypes module (GH-17158) files: A Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst M Doc/library/ctypes.rst M Lib/ctypes/__init__.py M Modules/_ctypes/_ctypes.c M Modules/_ctypes/callproc.c diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 1f84b7ab29839..e0bc28f5e5058 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1526,6 +1526,12 @@ object is available: ``ctypes.dlsym`` with arguments ``library`` (the library object) and ``name`` (the symbol's name as a string or integer). +.. audit-event:: ctypes.dlsym/handle handle,name ctypes.LibraryLoader + + In cases when only the library handle is available rather than the object, + accessing a function raises an auditing event ``ctypes.dlsym/handle`` with + arguments ``handle`` (the raw library handle) and ``name``. + .. _ctypes-foreign-functions: Foreign functions @@ -1611,6 +1617,19 @@ They are instances of a private class: passed arguments. +.. audit-event:: ctypes.seh_exception code foreign-functions + + On Windows, when a foreign function call raises a system exception (for + example, due to an access violation), it will be captured and replaced with + a suitable Python exception. Further, an auditing event + ``ctypes.seh_exception`` with argument ``code`` will be raised, allowing an + audit hook to replace the exception with its own. + +.. audit-event:: ctypes.call_function func_pointer,arguments ctype-foreign-functions + + Some ways to invoke foreign function calls may raise an auditing event + ``ctypes.call_function`` with arguments ``function pointer`` and ``arguments``. + .. _ctypes-function-prototypes: Function prototypes @@ -1802,6 +1821,8 @@ Utility functions Returns the address of the memory buffer as integer. *obj* must be an instance of a ctypes type. + .. audit-event:: ctypes.addressof obj ctypes.addressof + .. function:: alignment(obj_or_type) @@ -1844,6 +1865,7 @@ Utility functions termination character. An integer can be passed as second argument which allows specifying the size of the array if the length of the bytes should not be used. + .. audit-event:: ctypes.create_string_buffer init,size ctypes.create_string_buffer .. function:: create_unicode_buffer(init_or_size, size=None) @@ -1860,6 +1882,7 @@ Utility functions allows specifying the size of the array if the length of the string should not be used. + .. audit-event:: ctypes.create_unicode_buffer init,size ctypes.create_unicode_buffer .. function:: DllCanUnloadNow() @@ -1917,11 +1940,15 @@ Utility functions Returns the current value of the ctypes-private copy of the system :data:`errno` variable in the calling thread. + .. audit-event:: ctypes.get_errno "" ctypes.get_errno + .. function:: get_last_error() Windows only: returns the current value of the ctypes-private copy of the system :data:`LastError` variable in the calling thread. + .. audit-event:: ctypes.get_last_error "" ctypes.get_last_error + .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from @@ -1965,6 +1992,7 @@ Utility functions Set the current value of the ctypes-private copy of the system :data:`errno` variable in the calling thread to *value* and return the previous value. + .. audit-event:: ctypes.set_errno errno ctypes.set_errno .. function:: set_last_error(value) @@ -1973,6 +2001,7 @@ Utility functions :data:`LastError` variable in the calling thread to *value* and return the previous value. + .. audit-event:: ctypes.set_last_error error ctypes.set_last_error .. function:: sizeof(obj_or_type) @@ -1987,6 +2016,8 @@ Utility functions object. If size is specified, it is used as size, otherwise the string is assumed to be zero-terminated. + .. audit-event:: ctypes.string_at address,size ctypes.string_at + .. function:: WinError(code=None, descr=None) @@ -2007,6 +2038,8 @@ Utility functions characters of the string, otherwise the string is assumed to be zero-terminated. + .. audit-event:: ctypes.wstring_at address,size ctypes.wstring_at + .. _ctypes-data-types: @@ -2034,6 +2067,7 @@ Data types source buffer in bytes; the default is zero. If the source buffer is not large enough a :exc:`ValueError` is raised. + .. audit-event:: ctypes.cdata/buffer pointer,size,offset ctypes._CData.from_buffer .. method:: _CData.from_buffer_copy(source[, offset]) @@ -2043,6 +2077,8 @@ Data types is zero. If the source buffer is not large enough a :exc:`ValueError` is raised. + .. audit-event:: ctypes.cdata/buffer pointer,size,offset ctypes._CData.from_buffer_copy + .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 128155dbf4f2d..8f0991147d72f 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -52,11 +52,13 @@ def create_string_buffer(init, size=None): if isinstance(init, bytes): if size is None: size = len(init)+1 + _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): + _sys.audit("ctypes.create_string_buffer", None, init) buftype = c_char * init buf = buftype() return buf @@ -283,11 +285,13 @@ def create_unicode_buffer(init, size=None): # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for # trailing NUL character. size = len(init) + 1 + _sys.audit("ctypes.create_unicode_buffer", init, size) buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): + _sys.audit("ctypes.create_unicode_buffer", None, init) buftype = c_wchar * init buf = buftype() return buf diff --git a/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst b/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst new file mode 100644 index 0000000000000..0373c14d0a1cd --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst @@ -0,0 +1 @@ +Add additional audit events for the :mod:`ctypes` module. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index b4a3fc433d279..d38d892be621c 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -641,6 +641,12 @@ CDataType_from_buffer(PyObject *type, PyObject *args) return NULL; } + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) { + Py_DECREF(mv); + return NULL; + } + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); if (result == NULL) { Py_DECREF(mv); @@ -691,6 +697,12 @@ CDataType_from_buffer_copy(PyObject *type, PyObject *args) return NULL; } + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) { + PyBuffer_Release(&buffer); + return NULL; + } + result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); if (result != NULL) { memcpy(((CDataObject *)result)->b_ptr, @@ -714,6 +726,9 @@ CDataType_in_dll(PyObject *type, PyObject *args) if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name)) return NULL; + if (PySys_Audit("ctypes.dlsym", "O", args) < 0) { + return NULL; + } obj = PyObject_GetAttrString(dll, "_handle"); if (!obj) @@ -5535,6 +5550,9 @@ create_comerror(void) static PyObject * string_at(const char *ptr, int size) { + if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) { + return NULL; + } if (size == -1) return PyBytes_FromStringAndSize(ptr, strlen(ptr)); return PyBytes_FromStringAndSize(ptr, size); @@ -5626,6 +5644,9 @@ static PyObject * wstring_at(const wchar_t *ptr, int size) { Py_ssize_t ssize = size; + if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) { + return NULL; + } if (ssize == -1) ssize = wcslen(ptr); return PyUnicode_FromWideChar(ptr, ssize); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index a13c89fa82624..71060148d6651 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -199,8 +199,9 @@ set_error_internal(PyObject *self, PyObject *args, int index) PyObject *errobj; int *space; - if (!PyArg_ParseTuple(args, "i", &new_errno)) + if (!PyArg_ParseTuple(args, "i", &new_errno)) { return NULL; + } errobj = _ctypes_get_errobj(&space); if (errobj == NULL) return NULL; @@ -213,12 +214,18 @@ set_error_internal(PyObject *self, PyObject *args, int index) static PyObject * get_errno(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.get_errno", NULL) < 0) { + return NULL; + } return get_error_internal(self, args, 0); } static PyObject * set_errno(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.set_errno", "O", args) < 0) { + return NULL; + } return set_error_internal(self, args, 0); } @@ -227,12 +234,18 @@ set_errno(PyObject *self, PyObject *args) static PyObject * get_last_error(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.get_last_error", NULL) < 0) { + return NULL; + } return get_error_internal(self, args, 1); } static PyObject * set_last_error(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.set_last_error", "O", args) < 0) { + return NULL; + } return set_error_internal(self, args, 1); } @@ -262,6 +275,11 @@ static WCHAR *FormatError(DWORD code) #ifndef DONT_USE_SEH static void SetException(DWORD code, EXCEPTION_RECORD *pr) { + if (PySys_Audit("ctypes.seh_exception", "I", code) < 0) { + /* An exception was set by the audit hook */ + return; + } + /* The 'code' is a normal win32 error code so it could be handled by PyErr_SetFromWindowsErr(). However, for some errors, we have additional information not included in the error code. We handle those here and @@ -1427,6 +1445,9 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O&s:dlsym", &_parse_voidp, &handle, &name)) return NULL; + if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) { + return NULL; + } ptr = ctypes_dlsym((void*)handle, name); if (!ptr) { PyErr_SetString(PyExc_OSError, @@ -1454,6 +1475,10 @@ call_function(PyObject *self, PyObject *args) &_parse_voidp, &func, &PyTuple_Type, &arguments)) return NULL; + if (PySys_Audit("ctypes.call_function", "nO", + (Py_ssize_t)func, arguments) < 0) { + return NULL; + } result = _ctypes_callproc((PPROC)func, arguments, @@ -1485,6 +1510,10 @@ call_cdeclfunction(PyObject *self, PyObject *args) &_parse_voidp, &func, &PyTuple_Type, &arguments)) return NULL; + if (PySys_Audit("ctypes.call_function", "nO", + (Py_ssize_t)func, arguments) < 0) { + return NULL; + } result = _ctypes_callproc((PPROC)func, arguments, @@ -1597,11 +1626,15 @@ static const char addressof_doc[] = static PyObject * addressof(PyObject *self, PyObject *obj) { - if (CDataObject_Check(obj)) - return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); - PyErr_SetString(PyExc_TypeError, - "invalid type"); - return NULL; + if (!CDataObject_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "invalid type"); + return NULL; + } + if (PySys_Audit("ctypes.addressof", "O", obj) < 0) { + return NULL; + } + return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); } static int @@ -1615,8 +1648,12 @@ static PyObject * My_PyObj_FromPtr(PyObject *self, PyObject *args) { PyObject *ob; - if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) + if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { return NULL; + } + if (PySys_Audit("ctypes.PyObj_FromPtr", "O", ob) < 0) { + return NULL; + } Py_INCREF(ob); return ob; } From webhook-mailer at python.org Mon Nov 18 14:53:44 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 19:53:44 -0000 Subject: [Python-checkins] bpo-38622: Add missing audit events for ctypes module (GH-17158) Message-ID: https://github.com/python/cpython/commit/47db7439dd858c3634212c71137eb130f811bda4 commit: 47db7439dd858c3634212c71137eb130f811bda4 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T11:53:34-08:00 summary: bpo-38622: Add missing audit events for ctypes module (GH-17158) (cherry picked from commit 00923c63995e34cdc25d699478f113de99a69df9) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst M Doc/library/ctypes.rst M Lib/ctypes/__init__.py M Modules/_ctypes/_ctypes.c M Modules/_ctypes/callproc.c diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 1f84b7ab29839..e0bc28f5e5058 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1526,6 +1526,12 @@ object is available: ``ctypes.dlsym`` with arguments ``library`` (the library object) and ``name`` (the symbol's name as a string or integer). +.. audit-event:: ctypes.dlsym/handle handle,name ctypes.LibraryLoader + + In cases when only the library handle is available rather than the object, + accessing a function raises an auditing event ``ctypes.dlsym/handle`` with + arguments ``handle`` (the raw library handle) and ``name``. + .. _ctypes-foreign-functions: Foreign functions @@ -1611,6 +1617,19 @@ They are instances of a private class: passed arguments. +.. audit-event:: ctypes.seh_exception code foreign-functions + + On Windows, when a foreign function call raises a system exception (for + example, due to an access violation), it will be captured and replaced with + a suitable Python exception. Further, an auditing event + ``ctypes.seh_exception`` with argument ``code`` will be raised, allowing an + audit hook to replace the exception with its own. + +.. audit-event:: ctypes.call_function func_pointer,arguments ctype-foreign-functions + + Some ways to invoke foreign function calls may raise an auditing event + ``ctypes.call_function`` with arguments ``function pointer`` and ``arguments``. + .. _ctypes-function-prototypes: Function prototypes @@ -1802,6 +1821,8 @@ Utility functions Returns the address of the memory buffer as integer. *obj* must be an instance of a ctypes type. + .. audit-event:: ctypes.addressof obj ctypes.addressof + .. function:: alignment(obj_or_type) @@ -1844,6 +1865,7 @@ Utility functions termination character. An integer can be passed as second argument which allows specifying the size of the array if the length of the bytes should not be used. + .. audit-event:: ctypes.create_string_buffer init,size ctypes.create_string_buffer .. function:: create_unicode_buffer(init_or_size, size=None) @@ -1860,6 +1882,7 @@ Utility functions allows specifying the size of the array if the length of the string should not be used. + .. audit-event:: ctypes.create_unicode_buffer init,size ctypes.create_unicode_buffer .. function:: DllCanUnloadNow() @@ -1917,11 +1940,15 @@ Utility functions Returns the current value of the ctypes-private copy of the system :data:`errno` variable in the calling thread. + .. audit-event:: ctypes.get_errno "" ctypes.get_errno + .. function:: get_last_error() Windows only: returns the current value of the ctypes-private copy of the system :data:`LastError` variable in the calling thread. + .. audit-event:: ctypes.get_last_error "" ctypes.get_last_error + .. function:: memmove(dst, src, count) Same as the standard C memmove library function: copies *count* bytes from @@ -1965,6 +1992,7 @@ Utility functions Set the current value of the ctypes-private copy of the system :data:`errno` variable in the calling thread to *value* and return the previous value. + .. audit-event:: ctypes.set_errno errno ctypes.set_errno .. function:: set_last_error(value) @@ -1973,6 +2001,7 @@ Utility functions :data:`LastError` variable in the calling thread to *value* and return the previous value. + .. audit-event:: ctypes.set_last_error error ctypes.set_last_error .. function:: sizeof(obj_or_type) @@ -1987,6 +2016,8 @@ Utility functions object. If size is specified, it is used as size, otherwise the string is assumed to be zero-terminated. + .. audit-event:: ctypes.string_at address,size ctypes.string_at + .. function:: WinError(code=None, descr=None) @@ -2007,6 +2038,8 @@ Utility functions characters of the string, otherwise the string is assumed to be zero-terminated. + .. audit-event:: ctypes.wstring_at address,size ctypes.wstring_at + .. _ctypes-data-types: @@ -2034,6 +2067,7 @@ Data types source buffer in bytes; the default is zero. If the source buffer is not large enough a :exc:`ValueError` is raised. + .. audit-event:: ctypes.cdata/buffer pointer,size,offset ctypes._CData.from_buffer .. method:: _CData.from_buffer_copy(source[, offset]) @@ -2043,6 +2077,8 @@ Data types is zero. If the source buffer is not large enough a :exc:`ValueError` is raised. + .. audit-event:: ctypes.cdata/buffer pointer,size,offset ctypes._CData.from_buffer_copy + .. method:: from_address(address) This method returns a ctypes type instance using the memory specified by diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 128155dbf4f2d..8f0991147d72f 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -52,11 +52,13 @@ def create_string_buffer(init, size=None): if isinstance(init, bytes): if size is None: size = len(init)+1 + _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): + _sys.audit("ctypes.create_string_buffer", None, init) buftype = c_char * init buf = buftype() return buf @@ -283,11 +285,13 @@ def create_unicode_buffer(init, size=None): # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for # trailing NUL character. size = len(init) + 1 + _sys.audit("ctypes.create_unicode_buffer", init, size) buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): + _sys.audit("ctypes.create_unicode_buffer", None, init) buftype = c_wchar * init buf = buftype() return buf diff --git a/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst b/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst new file mode 100644 index 0000000000000..0373c14d0a1cd --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst @@ -0,0 +1 @@ +Add additional audit events for the :mod:`ctypes` module. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 13f9f212236ed..347a3656b6257 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -641,6 +641,12 @@ CDataType_from_buffer(PyObject *type, PyObject *args) return NULL; } + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) { + Py_DECREF(mv); + return NULL; + } + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); if (result == NULL) { Py_DECREF(mv); @@ -691,6 +697,12 @@ CDataType_from_buffer_copy(PyObject *type, PyObject *args) return NULL; } + if (PySys_Audit("ctypes.cdata/buffer", "nnn", + (Py_ssize_t)buffer.buf, buffer.len, offset) < 0) { + PyBuffer_Release(&buffer); + return NULL; + } + result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); if (result != NULL) { memcpy(((CDataObject *)result)->b_ptr, @@ -714,6 +726,9 @@ CDataType_in_dll(PyObject *type, PyObject *args) if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name)) return NULL; + if (PySys_Audit("ctypes.dlsym", "O", args) < 0) { + return NULL; + } obj = PyObject_GetAttrString(dll, "_handle"); if (!obj) @@ -5534,6 +5549,9 @@ create_comerror(void) static PyObject * string_at(const char *ptr, int size) { + if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) { + return NULL; + } if (size == -1) return PyBytes_FromStringAndSize(ptr, strlen(ptr)); return PyBytes_FromStringAndSize(ptr, size); @@ -5625,6 +5643,9 @@ static PyObject * wstring_at(const wchar_t *ptr, int size) { Py_ssize_t ssize = size; + if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) { + return NULL; + } if (ssize == -1) ssize = wcslen(ptr); return PyUnicode_FromWideChar(ptr, ssize); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index d9bdd9881333d..7fb570ed37f78 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -199,8 +199,9 @@ set_error_internal(PyObject *self, PyObject *args, int index) PyObject *errobj; int *space; - if (!PyArg_ParseTuple(args, "i", &new_errno)) + if (!PyArg_ParseTuple(args, "i", &new_errno)) { return NULL; + } errobj = _ctypes_get_errobj(&space); if (errobj == NULL) return NULL; @@ -213,12 +214,18 @@ set_error_internal(PyObject *self, PyObject *args, int index) static PyObject * get_errno(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.get_errno", NULL) < 0) { + return NULL; + } return get_error_internal(self, args, 0); } static PyObject * set_errno(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.set_errno", "O", args) < 0) { + return NULL; + } return set_error_internal(self, args, 0); } @@ -227,12 +234,18 @@ set_errno(PyObject *self, PyObject *args) static PyObject * get_last_error(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.get_last_error", NULL) < 0) { + return NULL; + } return get_error_internal(self, args, 1); } static PyObject * set_last_error(PyObject *self, PyObject *args) { + if (PySys_Audit("ctypes.set_last_error", "O", args) < 0) { + return NULL; + } return set_error_internal(self, args, 1); } @@ -262,6 +275,11 @@ static WCHAR *FormatError(DWORD code) #ifndef DONT_USE_SEH static void SetException(DWORD code, EXCEPTION_RECORD *pr) { + if (PySys_Audit("ctypes.seh_exception", "I", code) < 0) { + /* An exception was set by the audit hook */ + return; + } + /* The 'code' is a normal win32 error code so it could be handled by PyErr_SetFromWindowsErr(). However, for some errors, we have additional information not included in the error code. We handle those here and @@ -1427,6 +1445,9 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O&s:dlsym", &_parse_voidp, &handle, &name)) return NULL; + if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) { + return NULL; + } ptr = ctypes_dlsym((void*)handle, name); if (!ptr) { PyErr_SetString(PyExc_OSError, @@ -1454,6 +1475,10 @@ call_function(PyObject *self, PyObject *args) &_parse_voidp, &func, &PyTuple_Type, &arguments)) return NULL; + if (PySys_Audit("ctypes.call_function", "nO", + (Py_ssize_t)func, arguments) < 0) { + return NULL; + } result = _ctypes_callproc((PPROC)func, arguments, @@ -1485,6 +1510,10 @@ call_cdeclfunction(PyObject *self, PyObject *args) &_parse_voidp, &func, &PyTuple_Type, &arguments)) return NULL; + if (PySys_Audit("ctypes.call_function", "nO", + (Py_ssize_t)func, arguments) < 0) { + return NULL; + } result = _ctypes_callproc((PPROC)func, arguments, @@ -1597,11 +1626,15 @@ static const char addressof_doc[] = static PyObject * addressof(PyObject *self, PyObject *obj) { - if (CDataObject_Check(obj)) - return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); - PyErr_SetString(PyExc_TypeError, - "invalid type"); - return NULL; + if (!CDataObject_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "invalid type"); + return NULL; + } + if (PySys_Audit("ctypes.addressof", "O", obj) < 0) { + return NULL; + } + return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); } static int @@ -1615,8 +1648,12 @@ static PyObject * My_PyObj_FromPtr(PyObject *self, PyObject *args) { PyObject *ob; - if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) + if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { return NULL; + } + if (PySys_Audit("ctypes.PyObj_FromPtr", "O", ob) < 0) { + return NULL; + } Py_INCREF(ob); return ob; } From webhook-mailer at python.org Mon Nov 18 16:30:06 2019 From: webhook-mailer at python.org (Steve Dower) Date: Mon, 18 Nov 2019 21:30:06 -0000 Subject: [Python-checkins] bpo-38622: Ensure ctypes.PyObj_FromPtr audit event passes tuples as a single argument (GH-17243) Message-ID: https://github.com/python/cpython/commit/dcf1f83de8678b09df5bd7d04ca5f4ef1cd02aca commit: dcf1f83de8678b09df5bd7d04ca5f4ef1cd02aca branch: master author: Steve Dower committer: GitHub date: 2019-11-18T13:30:01-08:00 summary: bpo-38622: Ensure ctypes.PyObj_FromPtr audit event passes tuples as a single argument (GH-17243) files: M Modules/_ctypes/callproc.c diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 71060148d6651..7b13fa041a205 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1631,7 +1631,7 @@ addressof(PyObject *self, PyObject *obj) "invalid type"); return NULL; } - if (PySys_Audit("ctypes.addressof", "O", obj) < 0) { + if (PySys_Audit("ctypes.addressof", "(O)", obj) < 0) { return NULL; } return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); @@ -1651,7 +1651,7 @@ My_PyObj_FromPtr(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { return NULL; } - if (PySys_Audit("ctypes.PyObj_FromPtr", "O", ob) < 0) { + if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) { return NULL; } Py_INCREF(ob); From webhook-mailer at python.org Mon Nov 18 16:58:07 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 21:58:07 -0000 Subject: [Python-checkins] bpo-38722: Runpy use io.open_code() (GH-17234) Message-ID: https://github.com/python/cpython/commit/e37767bee1f7f1940b30768d21bfe2ae68c20a5f commit: e37767bee1f7f1940b30768d21bfe2ae68c20a5f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T13:58:02-08:00 summary: bpo-38722: Runpy use io.open_code() (GH-17234) https://bugs.python.org/issue38722 Automerge-Triggered-By: @taleinat (cherry picked from commit e243bae9999418859106328d9fce71815b7eb2fe) Co-authored-by: jsnklln files: A Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst M Lib/runpy.py diff --git a/Lib/runpy.py b/Lib/runpy.py index d86f0e4a3c49b..8adc91e32f319 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -13,6 +13,7 @@ import sys import importlib.machinery # importlib first so we can test #15386 via -m import importlib.util +import io import types from pkgutil import read_code, get_importer @@ -228,11 +229,11 @@ def _get_main_module_details(error=ImportError): def _get_code_from_file(run_name, fname): # Check for a compiled file first - with open(fname, "rb") as f: + with io.open_code(fname) as f: code = read_code(f) if code is None: # That didn't work, so try it as normal source code - with open(fname, "rb") as f: + with io.open_code(fname) as f: code = compile(f.read(), fname, 'exec') return code, fname diff --git a/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst b/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst new file mode 100644 index 0000000000000..0277d3e5689a2 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst @@ -0,0 +1,2 @@ +:mod:`runpy` now uses :meth:`io.open_code` to open code files. +Patch by Jason Killen. From webhook-mailer at python.org Mon Nov 18 16:59:55 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 18 Nov 2019 21:59:55 -0000 Subject: [Python-checkins] bpo-38622: Ensure ctypes.PyObj_FromPtr audit event passes tuples as a single argument (GH-17243) Message-ID: https://github.com/python/cpython/commit/bec7015dcc421a68cde030c5e4ca8e28408ef52d commit: bec7015dcc421a68cde030c5e4ca8e28408ef52d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-18T13:59:51-08:00 summary: bpo-38622: Ensure ctypes.PyObj_FromPtr audit event passes tuples as a single argument (GH-17243) (cherry picked from commit dcf1f83de8678b09df5bd7d04ca5f4ef1cd02aca) Co-authored-by: Steve Dower files: M Modules/_ctypes/callproc.c diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 7fb570ed37f78..77492e650ea48 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1631,7 +1631,7 @@ addressof(PyObject *self, PyObject *obj) "invalid type"); return NULL; } - if (PySys_Audit("ctypes.addressof", "O", obj) < 0) { + if (PySys_Audit("ctypes.addressof", "(O)", obj) < 0) { return NULL; } return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr); @@ -1651,7 +1651,7 @@ My_PyObj_FromPtr(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) { return NULL; } - if (PySys_Audit("ctypes.PyObj_FromPtr", "O", ob) < 0) { + if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) { return NULL; } Py_INCREF(ob); From webhook-mailer at python.org Mon Nov 18 20:37:05 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Tue, 19 Nov 2019 01:37:05 -0000 Subject: [Python-checkins] Minor fixes to the formatting of the notes of Modules/gcmodule.c (GH-17247) Message-ID: https://github.com/python/cpython/commit/b028f589ddf6041d2fab7eb50384588f199864b3 commit: b028f589ddf6041d2fab7eb50384588f199864b3 branch: master author: Pablo Galindo committer: GitHub date: 2019-11-19T01:36:57Z summary: Minor fixes to the formatting of the notes of Modules/gcmodule.c (GH-17247) files: M Modules/gcmodule.c diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index b258a0f6e1180..cb7a3de57a326 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1088,7 +1088,7 @@ deduce_unreachable(PyGC_Head *base, PyGC_Head *unreachable) { * NOTE: This used to move the reachable objects into a reachable * set instead. But most things usually turn out to be reachable, * so it's more efficient to move the unreachable things. See note - ^ [REACHABLE OR UNREACHABLE?} at the file end. + ^ [REACHABLE OR UNREACHABLE?] at the file end. */ gc_list_init(unreachable); move_unreachable(base, unreachable); // gc_prev is pointer again @@ -2188,7 +2188,7 @@ PyObject_GC_Del(void *op) /* ------------------------------------------------------------------------ Notes -[REACHABLE OR UNREACHABLE?} +[REACHABLE OR UNREACHABLE?] It "sounds slick" to move the unreachable objects, until you think about it - the reason it pays isn't actually obvious. From webhook-mailer at python.org Mon Nov 18 21:04:07 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Tue, 19 Nov 2019 02:04:07 -0000 Subject: [Python-checkins] Add @pablogsal to code owners file for the garbage collector (GH-17248) Message-ID: https://github.com/python/cpython/commit/02b8051a5e21f3db6af80dc5526156d7cac2afa0 commit: 02b8051a5e21f3db6af80dc5526156d7cac2afa0 branch: master author: Pablo Galindo committer: GitHub date: 2019-11-19T02:03:55Z summary: Add @pablogsal to code owners file for the garbage collector (GH-17248) Add myself to the codeowners file as I would like to be automatically added as a reviewer for PRs that touch that component and its documentation. files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index af5deea722625..0df7b5d28d9b0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -67,6 +67,10 @@ Include/pytime.h @pganssle @abalkin **/*imap* @python/email-team **/*poplib* @python/email-team +# Garbage collector +/Modules/gcmodule.c @pablogsal +/Doc/library/gc.rst @pablogsal + # Parser/Pgen /Parser/pgen/ @pablogsal From webhook-mailer at python.org Tue Nov 19 00:54:31 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 19 Nov 2019 05:54:31 -0000 Subject: [Python-checkins] bpo-38807: Add os.PathLike to exception message raised by _check_arg_types (#17160) Message-ID: https://github.com/python/cpython/commit/fe75b62575bcfdf1c39be71c1e50257832a596db commit: fe75b62575bcfdf1c39be71c1e50257832a596db branch: master author: Tom?s Far?as committer: Raymond Hettinger date: 2019-11-18T21:54:00-08:00 summary: bpo-38807: Add os.PathLike to exception message raised by _check_arg_types (#17160) files: A Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst M Lib/genericpath.py diff --git a/Lib/genericpath.py b/Lib/genericpath.py index db11f67d54cc2..ce36451a3af01 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -149,7 +149,7 @@ def _check_arg_types(funcname, *args): elif isinstance(s, bytes): hasbytes = True else: - raise TypeError('%s() argument must be str or bytes, not %r' % - (funcname, s.__class__.__name__)) from None + raise TypeError(f'{funcname}() argument must be str, bytes, or ' + f'os.PathLike object, not {s.__class__.__name__!r}') from None if hasstr and hasbytes: raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst b/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst new file mode 100644 index 0000000000000..2bd7e3deb19ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst @@ -0,0 +1 @@ +Update :exc:`TypeError` messages for :meth:`os.path.join` to include :class:`os.PathLike` objects as acceptable input types. \ No newline at end of file From webhook-mailer at python.org Tue Nov 19 01:46:18 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 19 Nov 2019 06:46:18 -0000 Subject: [Python-checkins] bpo-38807: Add os.PathLike to exception message raised by _check_arg_types (GH-17160) (GH-17249) Message-ID: https://github.com/python/cpython/commit/b5bb3b637c6b55f49d8979a5f489d01a67c4f917 commit: b5bb3b637c6b55f49d8979a5f489d01a67c4f917 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Raymond Hettinger date: 2019-11-18T22:46:10-08:00 summary: bpo-38807: Add os.PathLike to exception message raised by _check_arg_types (GH-17160) (GH-17249) (cherry picked from commit fe75b62575bcfdf1c39be71c1e50257832a596db) Co-authored-by: Tom?s Far?as files: A Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst M Lib/genericpath.py diff --git a/Lib/genericpath.py b/Lib/genericpath.py index db11f67d54cc2..ce36451a3af01 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -149,7 +149,7 @@ def _check_arg_types(funcname, *args): elif isinstance(s, bytes): hasbytes = True else: - raise TypeError('%s() argument must be str or bytes, not %r' % - (funcname, s.__class__.__name__)) from None + raise TypeError(f'{funcname}() argument must be str, bytes, or ' + f'os.PathLike object, not {s.__class__.__name__!r}') from None if hasstr and hasbytes: raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst b/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst new file mode 100644 index 0000000000000..2bd7e3deb19ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst @@ -0,0 +1 @@ +Update :exc:`TypeError` messages for :meth:`os.path.join` to include :class:`os.PathLike` objects as acceptable input types. \ No newline at end of file From webhook-mailer at python.org Tue Nov 19 02:16:31 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Tue, 19 Nov 2019 07:16:31 -0000 Subject: [Python-checkins] Clean up module initialization. (GH-17215) Message-ID: https://github.com/python/cpython/commit/79e18ec75d28fbb2f5a9d1d030a10d66ced38742 commit: 79e18ec75d28fbb2f5a9d1d030a10d66ced38742 branch: master author: Brandt Bucher committer: Raymond Hettinger date: 2019-11-18T23:16:23-08:00 summary: Clean up module initialization. (GH-17215) files: M Modules/_statisticsmodule.c diff --git a/Modules/_statisticsmodule.c b/Modules/_statisticsmodule.c index a646e96d0165c..fcdc9cee4d1a8 100644 --- a/Modules/_statisticsmodule.c +++ b/Modules/_statisticsmodule.c @@ -144,7 +144,5 @@ static struct PyModuleDef statisticsmodule = { PyMODINIT_FUNC PyInit__statistics(void) { - PyObject *m = PyModule_Create(&statisticsmodule); - if (!m) return NULL; - return m; + return PyModule_Create(&statisticsmodule); } From webhook-mailer at python.org Tue Nov 19 07:05:51 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 12:05:51 -0000 Subject: [Python-checkins] Add missing comma and period in unittest docs (GH-17211) Message-ID: https://github.com/python/cpython/commit/b1f160a236cb590b1c1a678ca5fc19d5c75dcd83 commit: b1f160a236cb590b1c1a678ca5fc19d5c75dcd83 branch: master author: Jules Lasne (jlasne) committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-19T04:05:45-08:00 summary: Add missing comma and period in unittest docs (GH-17211) Automerge-Triggered-By: @csabella files: M Doc/library/unittest.rst diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 9e66a2c1c220a..e2e4f2cdc220a 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1563,7 +1563,7 @@ Test cases if __name__ == "__main__": unittest.main() - After running the test ``events`` would contain ``["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]`` + After running the test, ``events`` would contain ``["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]``. .. class:: FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) From webhook-mailer at python.org Tue Nov 19 07:13:11 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 12:13:11 -0000 Subject: [Python-checkins] Add missing comma and period in unittest docs (GH-17211) Message-ID: https://github.com/python/cpython/commit/c749326d24bf407a18350f9753e75aa5564483c2 commit: c749326d24bf407a18350f9753e75aa5564483c2 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T04:12:58-08:00 summary: Add missing comma and period in unittest docs (GH-17211) Automerge-Triggered-By: @csabella (cherry picked from commit b1f160a236cb590b1c1a678ca5fc19d5c75dcd83) Co-authored-by: Jules Lasne (jlasne) files: M Doc/library/unittest.rst diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index eb6714a8c8ff9..a559d0988bee2 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1563,7 +1563,7 @@ Test cases if __name__ == "__main__": unittest.main() - After running the test ``events`` would contain ``["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]`` + After running the test, ``events`` would contain ``["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"]``. .. class:: FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None) From webhook-mailer at python.org Tue Nov 19 07:15:05 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 12:15:05 -0000 Subject: [Python-checkins] Added missing coma after end of list in subprocess.rst (GH-17217) Message-ID: https://github.com/python/cpython/commit/f25875af425a3480e557aaedf49c3bb867bcbd5d commit: f25875af425a3480e557aaedf49c3bb867bcbd5d branch: master author: Jules Lasne (jlasne) committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-19T04:14:53-08:00 summary: Added missing coma after end of list in subprocess.rst (GH-17217) Automerge-Triggered-By: @csabella files: M Doc/library/subprocess.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 19290bfc34c7d..f2e5463d755bb 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -630,7 +630,7 @@ functions. Popen and the other functions in this module that use it raise an :ref:`auditing event ` ``subprocess.Popen`` with arguments - ``executable``, ``args``, ``cwd``, ``env``. The value for ``args`` + ``executable``, ``args``, ``cwd``, and ``env``. The value for ``args`` may be a single string or a list of strings, depending on platform. .. versionchanged:: 3.2 From webhook-mailer at python.org Tue Nov 19 08:53:57 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 13:53:57 -0000 Subject: [Python-checkins] bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Message-ID: https://github.com/python/cpython/commit/8e0de2a4808d7c2f4adedabff89ee64e0338790a commit: 8e0de2a4808d7c2f4adedabff89ee64e0338790a branch: master author: Vincent Michel committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-19T05:53:52-08:00 summary: bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Ignore `GeneratorExit` exceptions when throwing an exception into the `aclose` coroutine of an asynchronous generator. https://bugs.python.org/issue35409 files: A Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst M Lib/test/test_asyncgen.py M Objects/genobject.c diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 23eb6a411cd19..58d8aee19adac 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -735,6 +735,33 @@ def foo(): self.loop.run_until_complete(run()) self.assertEqual(DONE, 10) + def test_async_gen_asyncio_aclose_12(self): + DONE = 0 + + async def target(): + await asyncio.sleep(0.01) + 1 / 0 + + async def foo(): + nonlocal DONE + task = asyncio.create_task(target()) + try: + yield 1 + finally: + try: + await task + except ZeroDivisionError: + DONE = 1 + + async def run(): + gen = foo() + it = gen.__aiter__() + await it.__anext__() + await gen.aclose() + + self.loop.run_until_complete(run()) + self.assertEqual(DONE, 1) + def test_async_gen_asyncio_asend_01(self): DONE = 0 diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst new file mode 100644 index 0000000000000..0f35a91ec74e6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst @@ -0,0 +1,2 @@ +Ignore GeneratorExit exceptions when throwing an exception into the aclose +coroutine of an asynchronous generator. diff --git a/Objects/genobject.c b/Objects/genobject.c index 98eb9c34c3dcd..c5fe9999af26e 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1932,6 +1932,17 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } return retval; } } From webhook-mailer at python.org Tue Nov 19 09:12:17 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 14:12:17 -0000 Subject: [Python-checkins] bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Message-ID: https://github.com/python/cpython/commit/6c3b471c8c0bfd49c664d8ee7e95da3710fd6069 commit: 6c3b471c8c0bfd49c664d8ee7e95da3710fd6069 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T06:12:06-08:00 summary: bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Ignore `GeneratorExit` exceptions when throwing an exception into the `aclose` coroutine of an asynchronous generator. https://bugs.python.org/issue35409 (cherry picked from commit 8e0de2a4808d7c2f4adedabff89ee64e0338790a) Co-authored-by: Vincent Michel files: A Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst M Lib/test/test_asyncgen.py M Objects/genobject.c diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 23eb6a411cd19..58d8aee19adac 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -735,6 +735,33 @@ def foo(): self.loop.run_until_complete(run()) self.assertEqual(DONE, 10) + def test_async_gen_asyncio_aclose_12(self): + DONE = 0 + + async def target(): + await asyncio.sleep(0.01) + 1 / 0 + + async def foo(): + nonlocal DONE + task = asyncio.create_task(target()) + try: + yield 1 + finally: + try: + await task + except ZeroDivisionError: + DONE = 1 + + async def run(): + gen = foo() + it = gen.__aiter__() + await it.__anext__() + await gen.aclose() + + self.loop.run_until_complete(run()) + self.assertEqual(DONE, 1) + def test_async_gen_asyncio_asend_01(self): DONE = 0 diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst new file mode 100644 index 0000000000000..0f35a91ec74e6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst @@ -0,0 +1,2 @@ +Ignore GeneratorExit exceptions when throwing an exception into the aclose +coroutine of an asynchronous generator. diff --git a/Objects/genobject.c b/Objects/genobject.c index 6285219bb2d71..5643553b708d1 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1947,6 +1947,17 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } return retval; } } From webhook-mailer at python.org Tue Nov 19 09:12:24 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 14:12:24 -0000 Subject: [Python-checkins] bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Message-ID: https://github.com/python/cpython/commit/4ffc569b47bef9f95e443f3c56f7e7e32cb440c0 commit: 4ffc569b47bef9f95e443f3c56f7e7e32cb440c0 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T06:12:12-08:00 summary: bpo-35409: Ignore GeneratorExit in async_gen_athrow_throw (GH-14755) Ignore `GeneratorExit` exceptions when throwing an exception into the `aclose` coroutine of an asynchronous generator. https://bugs.python.org/issue35409 (cherry picked from commit 8e0de2a4808d7c2f4adedabff89ee64e0338790a) Co-authored-by: Vincent Michel files: A Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst M Lib/test/test_asyncgen.py M Objects/genobject.c diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 94c2633f330a4..cca6d58417ac4 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -696,6 +696,33 @@ def foo(): self.loop.run_until_complete(run()) self.assertEqual(DONE, 10) + def test_async_gen_asyncio_aclose_12(self): + DONE = 0 + + async def target(): + await asyncio.sleep(0.01) + 1 / 0 + + async def foo(): + nonlocal DONE + task = asyncio.create_task(target()) + try: + yield 1 + finally: + try: + await task + except ZeroDivisionError: + DONE = 1 + + async def run(): + gen = foo() + it = gen.__aiter__() + await it.__anext__() + await gen.aclose() + + self.loop.run_until_complete(run()) + self.assertEqual(DONE, 1) + def test_async_gen_asyncio_asend_01(self): DONE = 0 diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst new file mode 100644 index 0000000000000..0f35a91ec74e6 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-07-13-18-01-13.bpo-35409.ozbcsR.rst @@ -0,0 +1,2 @@ +Ignore GeneratorExit exceptions when throwing an exception into the aclose +coroutine of an asynchronous generator. diff --git a/Objects/genobject.c b/Objects/genobject.c index 8a978b1a1fe02..7fc7a1f2aeb3d 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1920,6 +1920,17 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) PyErr_SetString(PyExc_RuntimeError, ASYNC_GEN_IGNORED_EXIT_MSG); return NULL; } + if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration) || + PyErr_ExceptionMatches(PyExc_GeneratorExit)) + { + /* when aclose() is called we don't want to propagate + StopAsyncIteration or GeneratorExit; just raise + StopIteration, signalling that this 'aclose()' await + is done. + */ + PyErr_Clear(); + PyErr_SetNone(PyExc_StopIteration); + } return retval; } } From webhook-mailer at python.org Tue Nov 19 14:16:59 2019 From: webhook-mailer at python.org (T. Wouters) Date: Tue, 19 Nov 2019 19:16:59 -0000 Subject: [Python-checkins] bpo-38823: Clean up refleak in fcntl module initialization. (GH-17236) Message-ID: https://github.com/python/cpython/commit/54b32c987146123f2237f0e21b1d02b1c1ebdf6f commit: 54b32c987146123f2237f0e21b1d02b1c1ebdf6f branch: master author: Brandt Bucher committer: T. Wouters date: 2019-11-19T11:16:29-08:00 summary: bpo-38823: Clean up refleak in fcntl module initialization. (GH-17236) files: M Modules/fcntlmodule.c diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 1e5b0f7faea6f..11906aa582929 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -668,8 +668,10 @@ PyInit_fcntl(void) return NULL; /* Add some symbolic constants to the module */ - if (all_ins(m) < 0) + if (all_ins(m) < 0) { + Py_DECREF(m); return NULL; + } return m; } From webhook-mailer at python.org Tue Nov 19 14:45:29 2019 From: webhook-mailer at python.org (Brett Cannon) Date: Tue, 19 Nov 2019 19:45:29 -0000 Subject: [Python-checkins] bpo-38839: Fix some unused functions in tests (GH-17189) Message-ID: https://github.com/python/cpython/commit/892221bfa04a41cf581f988ba19dc263f557e157 commit: 892221bfa04a41cf581f988ba19dc263f557e157 branch: master author: Adam Johnson committer: Brett Cannon <54418+brettcannon at users.noreply.github.com> date: 2019-11-19T11:45:20-08:00 summary: bpo-38839: Fix some unused functions in tests (GH-17189) files: A Misc/NEWS.d/next/Tests/2019-11-18-22-10-55.bpo-38839.di6tXv.rst M Lib/distutils/tests/support.py M Lib/test/test_asynchat.py M Lib/test/test_buffer.py M Lib/test/test_builtin.py M Lib/test/test_code.py M Lib/test/test_importlib/import_/test_relative_imports.py M Lib/unittest/test/testmock/testasync.py M Tools/ccbench/ccbench.py diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py index 041309851d0f3..259af882ec0e9 100644 --- a/Lib/distutils/tests/support.py +++ b/Lib/distutils/tests/support.py @@ -39,8 +39,6 @@ def _log(self, level, msg, args): self.logs.append((level, msg, args)) def get_logs(self, *levels): - def _format(msg, args): - return msg % args return [msg % args for level, msg, args in self.logs if level in levels] diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py index 14c0ec43d422e..74041ed58ef70 100644 --- a/Lib/test/test_asynchat.py +++ b/Lib/test/test_asynchat.py @@ -73,14 +73,14 @@ def __init__(self, terminator, server_port): self.set_terminator(terminator) self.buffer = b"" - def handle_connect(self): - pass + def handle_connect(self): + pass - if sys.platform == 'darwin': - # select.poll returns a select.POLLHUP at the end of the tests - # on darwin, so just ignore it - def handle_expt(self): - pass + if sys.platform == 'darwin': + # select.poll returns a select.POLLHUP at the end of the tests + # on darwin, so just ignore it + def handle_expt(self): + pass def collect_incoming_data(self, data): self.buffer += data diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 5fa52bffc22be..0aa78016f5d1a 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -969,8 +969,6 @@ def check_memoryview(m, expected_readonly=readonly): m.tobytes() # Releasing mm didn't release m def verify_getbuf(self, orig_ex, ex, req, sliced=False): - def simple_fmt(ex): - return ex.format == '' or ex.format == 'B' def match(req, flag): return ((req&flag) == flag) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index abccf32227444..6a88454289d34 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -765,6 +765,7 @@ def test_hash(self): self.assertEqual(hash('spam'), hash(b'spam')) hash((0,1,2,3)) def f(): pass + hash(f) self.assertRaises(TypeError, hash, []) self.assertRaises(TypeError, hash, {}) # Bug 1536021: Allow hash to return long objects diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 0d80af44d9f1f..656c46cfaa757 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -241,7 +241,7 @@ def func(): def func2(): y = 2 return y - code2 = func.__code__ + code2 = func2.__code__ for attr, value in ( ("co_argcount", 0), diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py index 586a9bf4bc121..41aa18269952f 100644 --- a/Lib/test/test_importlib/import_/test_relative_imports.py +++ b/Lib/test/test_importlib/import_/test_relative_imports.py @@ -133,6 +133,7 @@ def callback(global_): self.assertEqual(module.__name__, 'pkg') self.assertTrue(hasattr(module, 'subpkg2')) self.assertEqual(module.subpkg2.attr, 'pkg.subpkg2.__init__') + self.relative_import_test(create, globals_, callback) def test_deep_import(self): # [deep import] diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 6b2d49d3e44d2..0d2cdb0069ff7 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -335,6 +335,7 @@ def test_is_AsyncMock_patch(self): @patch.object(AsyncClass, 'async_method', spec_set=True) def test_async(async_method): self.assertIsInstance(async_method, AsyncMock) + test_async() def test_is_async_AsyncMock(self): mock = AsyncMock(spec_set=AsyncClass.async_method) diff --git a/Misc/NEWS.d/next/Tests/2019-11-18-22-10-55.bpo-38839.di6tXv.rst b/Misc/NEWS.d/next/Tests/2019-11-18-22-10-55.bpo-38839.di6tXv.rst new file mode 100644 index 0000000000000..80c5a5bdfbba6 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-18-22-10-55.bpo-38839.di6tXv.rst @@ -0,0 +1 @@ +Fix some unused functions in tests. Patch by Adam Johnson. diff --git a/Tools/ccbench/ccbench.py b/Tools/ccbench/ccbench.py index 4f77a65f4d779..ab1465a276092 100644 --- a/Tools/ccbench/ccbench.py +++ b/Tools/ccbench/ccbench.py @@ -84,13 +84,6 @@ def task_regex(): pat = re.compile(r'^(\s*def\s)|(.*(? https://github.com/python/cpython/commit/c6b20be85c0de6f2355c67ae6e7e578941275cc0 commit: c6b20be85c0de6f2355c67ae6e7e578941275cc0 branch: master author: Jake Tesler committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-19T11:50:12-08:00 summary: bpo-38707: Fix for multiprocessing.Process MainThread.native_id (GH-17088) This PR implements a fix for `multiprocessing.Process` objects; the error occurs when Processes are created using either `fork` or `forkserver` as the `start_method`. In these instances, the `MainThread` of the newly created `Process` object retains all attributes from its parent's `MainThread` object, including the `native_id` attribute. The resulting behavior is such that the new process' `MainThread` captures an incorrect/outdated `native_id` (the parent's instead of its own). This change forces the Process object to update its `native_id` attribute during the bootstrap process. cc @vstinner https://bugs.python.org/issue38707 Automerge-Triggered-By: @pitrou files: A Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst M Lib/multiprocessing/process.py M Lib/test/_test_multiprocessing.py diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index c62c826cff958..be13c079bb89b 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -301,6 +301,8 @@ def _bootstrap(self, parent_sentinel=None): _current_process = self _parent_process = _ParentProcess( self._parent_name, self._parent_pid, parent_sentinel) + if threading._HAVE_THREAD_NATIVE_ID: + threading.main_thread()._set_native_id() try: util._finalizer_registry.clear() util._run_after_forkers() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index f7bebc6e8370b..611291cbbaf93 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -361,6 +361,28 @@ def test_process(self): self.assertNotIn(p, self.active_children()) close_queue(q) + @unittest.skipUnless(threading._HAVE_THREAD_NATIVE_ID, "needs native_id") + def test_process_mainthread_native_id(self): + if self.TYPE == 'threads': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + current_mainthread_native_id = threading.main_thread().native_id + + q = self.Queue(1) + p = self.Process(target=self._test_process_mainthread_native_id, args=(q,)) + p.start() + + child_mainthread_native_id = q.get() + p.join() + close_queue(q) + + self.assertNotEqual(current_mainthread_native_id, child_mainthread_native_id) + + @classmethod + def _test_process_mainthread_native_id(cls, q): + mainthread_native_id = threading.main_thread().native_id + q.put(mainthread_native_id) + @classmethod def _sleep_some(cls): time.sleep(100) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst new file mode 100644 index 0000000000000..4ef9ed81931b7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst @@ -0,0 +1 @@ +``MainThread.native_id`` is now correctly reset in child processes spawned using :class:`multiprocessing.Process`, instead of retaining the parent's value. From webhook-mailer at python.org Tue Nov 19 15:11:25 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 20:11:25 -0000 Subject: [Python-checkins] bpo-38707: Fix for multiprocessing.Process MainThread.native_id (GH-17088) Message-ID: https://github.com/python/cpython/commit/829593a9262e67c72167c6cb20d383203b2ea410 commit: 829593a9262e67c72167c6cb20d383203b2ea410 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T12:11:20-08:00 summary: bpo-38707: Fix for multiprocessing.Process MainThread.native_id (GH-17088) This PR implements a fix for `multiprocessing.Process` objects; the error occurs when Processes are created using either `fork` or `forkserver` as the `start_method`. In these instances, the `MainThread` of the newly created `Process` object retains all attributes from its parent's `MainThread` object, including the `native_id` attribute. The resulting behavior is such that the new process' `MainThread` captures an incorrect/outdated `native_id` (the parent's instead of its own). This change forces the Process object to update its `native_id` attribute during the bootstrap process. cc @vstinner https://bugs.python.org/issue38707 Automerge-Triggered-By: @pitrou (cherry picked from commit c6b20be85c0de6f2355c67ae6e7e578941275cc0) Co-authored-by: Jake Tesler files: A Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst M Lib/multiprocessing/process.py M Lib/test/_test_multiprocessing.py diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index c62c826cff958..be13c079bb89b 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -301,6 +301,8 @@ def _bootstrap(self, parent_sentinel=None): _current_process = self _parent_process = _ParentProcess( self._parent_name, self._parent_pid, parent_sentinel) + if threading._HAVE_THREAD_NATIVE_ID: + threading.main_thread()._set_native_id() try: util._finalizer_registry.clear() util._run_after_forkers() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 1474624ac5d5b..b7f3d253c4d13 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -367,6 +367,28 @@ def test_process(self): self.assertNotIn(p, self.active_children()) close_queue(q) + @unittest.skipUnless(threading._HAVE_THREAD_NATIVE_ID, "needs native_id") + def test_process_mainthread_native_id(self): + if self.TYPE == 'threads': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + current_mainthread_native_id = threading.main_thread().native_id + + q = self.Queue(1) + p = self.Process(target=self._test_process_mainthread_native_id, args=(q,)) + p.start() + + child_mainthread_native_id = q.get() + p.join() + close_queue(q) + + self.assertNotEqual(current_mainthread_native_id, child_mainthread_native_id) + + @classmethod + def _test_process_mainthread_native_id(cls, q): + mainthread_native_id = threading.main_thread().native_id + q.put(mainthread_native_id) + @classmethod def _sleep_some(cls): time.sleep(100) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst new file mode 100644 index 0000000000000..4ef9ed81931b7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-08-00-36-10.bpo-38707.SZL036.rst @@ -0,0 +1 @@ +``MainThread.native_id`` is now correctly reset in child processes spawned using :class:`multiprocessing.Process`, instead of retaining the parent's value. From webhook-mailer at python.org Tue Nov 19 16:34:07 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Tue, 19 Nov 2019 21:34:07 -0000 Subject: [Python-checkins] Remove binding of captured exceptions when not used to reduce the chances of creating cycles (GH-17246) Message-ID: https://github.com/python/cpython/commit/293dd23477eef6e7c1b1e26b5bb2c1e0d79ac3c2 commit: 293dd23477eef6e7c1b1e26b5bb2c1e0d79ac3c2 branch: master author: Pablo Galindo committer: GitHub date: 2019-11-19T21:34:03Z summary: Remove binding of captured exceptions when not used to reduce the chances of creating cycles (GH-17246) Capturing exceptions into names can lead to reference cycles though the __traceback__ attribute of the exceptions in some obscure cases that have been reported previously and fixed individually. As these variables are not used anyway, we can remove the binding to reduce the chances of creating reference cycles. See for example GH-13135 files: M Lib/asynchat.py M Lib/asyncio/proactor_events.py M Lib/asyncio/unix_events.py M Lib/codeop.py M Lib/ctypes/util.py M Lib/enum.py M Lib/filecmp.py M Lib/getpass.py M Lib/importlib/abc.py M Lib/lib2to3/main.py M Lib/msilib/__init__.py M Lib/multiprocessing/managers.py M Lib/multiprocessing/popen_fork.py M Lib/poplib.py M Lib/test/pythoninfo.py M Lib/test/test_cgitb.py M Lib/test/test_class.py M Lib/test/test_codecs.py M Lib/test/test_decimal.py M Lib/test/test_ftplib.py M Lib/test/test_sys_settrace.py M Lib/test/test_time.py M Lib/test/test_traceback.py M Lib/test/test_urllib2net.py M Lib/test/test_uuid.py M Lib/unittest/case.py M Lib/urllib/request.py M Lib/xml/sax/__init__.py diff --git a/Lib/asynchat.py b/Lib/asynchat.py index fc1146adbb10d..f4ba361bd4a3e 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -117,7 +117,7 @@ def handle_read(self): data = self.recv(self.ac_in_buffer_size) except BlockingIOError: return - except OSError as why: + except OSError: self.handle_error() return diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 830d8edc32f90..8338449aaa0a3 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -711,7 +711,7 @@ def close(self): raise exceptions.SendfileNotAvailableError("not a regular file") try: fsize = os.fstat(fileno).st_size - except OSError as err: + except OSError: raise exceptions.SendfileNotAvailableError("not a regular file") blocksize = count if count else fsize if not blocksize: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 66213728a3dcb..632546ad00817 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -330,7 +330,7 @@ def _child_watcher_callback(self, pid, returncode, transp): async def _sock_sendfile_native(self, sock, file, offset, count): try: os.sendfile - except AttributeError as exc: + except AttributeError: raise exceptions.SendfileNotAvailableError( "os.sendfile() is not available") try: @@ -339,7 +339,7 @@ def _child_watcher_callback(self, pid, returncode, transp): raise exceptions.SendfileNotAvailableError("not a regular file") try: fsize = os.fstat(fileno).st_size - except OSError as err: + except OSError: raise exceptions.SendfileNotAvailableError("not a regular file") blocksize = count if count else fsize if not blocksize: diff --git a/Lib/codeop.py b/Lib/codeop.py index e5c7adea54fbd..fc7e1e70ceafe 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -80,7 +80,7 @@ def _maybe_compile(compiler, source, filename, symbol): try: code = compiler(source, filename, symbol) - except SyntaxError as err: + except SyntaxError: pass try: diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 97973bce001d9..01176bf969657 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -302,7 +302,7 @@ def _findLib_ld(name): res = re.search(expr, os.fsdecode(out)) if res: result = res.group(0) - except Exception as e: + except Exception: pass # result will be None return result diff --git a/Lib/enum.py b/Lib/enum.py index 8a6e5d2e46d6b..06f42a978035b 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -420,7 +420,7 @@ def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, s if module is None: try: module = sys._getframe(2).f_globals['__name__'] - except (AttributeError, ValueError, KeyError) as exc: + except (AttributeError, ValueError, KeyError): pass if module is None: _make_class_unpicklable(enum_class) diff --git a/Lib/filecmp.py b/Lib/filecmp.py index e5ad8397e4c53..cfdca1e924f55 100644 --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -156,12 +156,12 @@ def phase2(self): # Distinguish files, directories, funnies ok = 1 try: a_stat = os.stat(a_path) - except OSError as why: + except OSError: # print('Can\'t stat', a_path, ':', why.args[1]) ok = 0 try: b_stat = os.stat(b_path) - except OSError as why: + except OSError: # print('Can\'t stat', b_path, ':', why.args[1]) ok = 0 diff --git a/Lib/getpass.py b/Lib/getpass.py index 36e17e4cb6965..6911f41d1f205 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -52,7 +52,7 @@ def unix_getpass(prompt='Password: ', stream=None): stack.enter_context(input) if not stream: stream = input - except OSError as e: + except OSError: # If that fails, see if stdin can be controlled. stack.close() try: diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 4b2d3de6d96f1..b1b5ccce4bd35 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -10,7 +10,7 @@ _frozen_importlib = None try: import _frozen_importlib_external -except ImportError as exc: +except ImportError: _frozen_importlib_external = _bootstrap_external import abc import warnings diff --git a/Lib/lib2to3/main.py b/Lib/lib2to3/main.py index d6b708848ede1..c51626babf8ec 100644 --- a/Lib/lib2to3/main.py +++ b/Lib/lib2to3/main.py @@ -90,11 +90,11 @@ def write_file(self, new_text, filename, old_text, encoding): if os.path.lexists(backup): try: os.remove(backup) - except OSError as err: + except OSError: self.log_message("Can't remove backup %s", backup) try: os.rename(filename, backup) - except OSError as err: + except OSError: self.log_message("Can't rename %s to %s", filename, backup) # Actually write the new file write = super(StdoutRefactoringTool, self).write_file diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py index 0bc8dd9952462..0e85aa28967ea 100644 --- a/Lib/msilib/__init__.py +++ b/Lib/msilib/__init__.py @@ -116,7 +116,7 @@ def add_data(db, table, values): raise TypeError("Unsupported type %s" % field.__class__.__name__) try: v.Modify(MSIMODIFY_INSERT, r) - except Exception as e: + except Exception: raise MSIError("Could not insert "+repr(values)+" into "+table) r.ClearData() diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 75b5150f821b1..1f9c2daa25d97 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -248,7 +248,7 @@ def serve_client(self, conn): try: obj, exposed, gettypeid = \ self.id_to_local_proxy_obj[ident] - except KeyError as second_ke: + except KeyError: raise ke if methodname not in exposed: @@ -296,7 +296,7 @@ def serve_client(self, conn): try: try: send(msg) - except Exception as e: + except Exception: send(('#UNSERIALIZABLE', format_exc())) except Exception as e: util.info('exception in thread serving %r', diff --git a/Lib/multiprocessing/popen_fork.py b/Lib/multiprocessing/popen_fork.py index 11e216072d091..a65b06f1b2c75 100644 --- a/Lib/multiprocessing/popen_fork.py +++ b/Lib/multiprocessing/popen_fork.py @@ -25,7 +25,7 @@ def poll(self, flag=os.WNOHANG): if self.returncode is None: try: pid, sts = os.waitpid(self.pid, flag) - except OSError as e: + except OSError: # Child process not yet created. See #1731717 # e.errno == errno.ECHILD == 10 return None diff --git a/Lib/poplib.py b/Lib/poplib.py index e3bd2ab1ebc8b..0b6750d230376 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -385,7 +385,7 @@ def _parsecap(line): for capline in rawcaps: capnm, capargs = _parsecap(capline) caps[capnm] = capargs - except error_proto as _err: + except error_proto: raise error_proto('-ERR CAPA not supported by server') return caps diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 797b3af7d3085..eab82c3631fd2 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -754,7 +754,7 @@ def collect_info(info): ): try: collect_func(info_add) - except Exception as exc: + except Exception: error = True print("ERROR: %s() failed" % (collect_func.__name__), file=sys.stderr) diff --git a/Lib/test/test_cgitb.py b/Lib/test/test_cgitb.py index e299ec3ec6ceb..8991bc1ff34ba 100644 --- a/Lib/test/test_cgitb.py +++ b/Lib/test/test_cgitb.py @@ -31,7 +31,7 @@ def test_html(self): def test_text(self): try: raise ValueError("Hello World") - except ValueError as err: + except ValueError: text = cgitb.text(sys.exc_info()) self.assertIn("ValueError", text) self.assertIn("Hello World", text) diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 456f1be30be04..7524f58a3ce73 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -529,7 +529,7 @@ class I: # In debug mode, printed XXX undetected error and # raises AttributeError I() - except AttributeError as x: + except AttributeError: pass else: self.fail("attribute error for I.__init__ got masked") diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index e1638c111681c..3aec34c7f167d 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -11,7 +11,7 @@ try: import _testcapi -except ImportError as exc: +except ImportError: _testcapi = None try: diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 1f37b5372a3e7..fe0cfc7b66d7e 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5600,13 +5600,13 @@ def doit(ty): args, kwds = mkargs(C, c_sig) try: getattr(c_type(9), attr)(*args, **kwds) - except Exception as err: + except Exception: raise TestFailed("invalid signature for %s: %s %s" % (c_func, args, kwds)) args, kwds = mkargs(P, p_sig) try: getattr(p_type(9), attr)(*args, **kwds) - except Exception as err: + except Exception: raise TestFailed("invalid signature for %s: %s %s" % (p_func, args, kwds)) doit('Decimal') diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index b0e46411a2e2b..b8eef82b15fb3 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -346,7 +346,7 @@ def _do_ssl_shutdown(self): if err.args[0] in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE): return - except OSError as err: + except OSError: # Any "socket error" corresponds to a SSL_ERROR_SYSCALL return # from OpenSSL's SSL_shutdown(), corresponding to a # closed socket condition. See also: diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index fdd789475d04d..d4e1ac2c83eff 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -161,8 +161,8 @@ def raises(): def test_raise(): try: raises() - except Exception as exc: - x = 1 + except Exception: + pass test_raise.events = [(0, 'call'), (1, 'line'), @@ -191,7 +191,7 @@ def _settrace_and_raise(tracefunc): def settrace_and_raise(tracefunc): try: _settrace_and_raise(tracefunc) - except RuntimeError as exc: + except RuntimeError: pass settrace_and_raise.events = [(2, 'exception'), diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 8d8d31e7825e6..80e43fafad813 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -825,7 +825,7 @@ def convert_values(ns_timestamps): try: result = pytime_converter(value, time_rnd) expected = expected_func(value) - except Exception as exc: + except Exception: self.fail("Error on timestamp conversion: %s" % debug_info) self.assertEqual(result, expected, diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 72dc7afb8c5cc..7135d997d54ab 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -313,7 +313,7 @@ def f(): with captured_output("stderr") as stderr_f: try: f() - except RecursionError as exc: + except RecursionError: render_exc() else: self.fail("no recursion occurred") @@ -360,7 +360,7 @@ def g(count=10): with captured_output("stderr") as stderr_g: try: g() - except ValueError as exc: + except ValueError: render_exc() else: self.fail("no value error was raised") @@ -396,7 +396,7 @@ def h(count=10): with captured_output("stderr") as stderr_h: try: h() - except ValueError as exc: + except ValueError: render_exc() else: self.fail("no value error was raised") @@ -424,7 +424,7 @@ def h(count=10): with captured_output("stderr") as stderr_g: try: g(traceback._RECURSIVE_CUTOFF) - except ValueError as exc: + except ValueError: render_exc() else: self.fail("no error raised") @@ -452,7 +452,7 @@ def h(count=10): with captured_output("stderr") as stderr_g: try: g(traceback._RECURSIVE_CUTOFF + 1) - except ValueError as exc: + except ValueError: render_exc() else: self.fail("no error raised") diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index 040a2ce276dbd..bb0500e12a49a 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -199,7 +199,7 @@ def test_sites_no_connection_close(self): try: with urllib.request.urlopen(URL) as res: pass - except ValueError as e: + except ValueError: self.fail("urlopen failed for site not sending \ Connection:close") else: diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index ddf7e6dc1b8e4..b76c60e1ce28b 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -471,7 +471,7 @@ def test_uuid1_eui64(self): # the value from too_large_getter above. try: self.uuid.uuid1(node=node) - except ValueError as e: + except ValueError: self.fail('uuid1 was given an invalid node ID') def test_uuid1(self): diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index bac9789c943fa..fa64a6ea2378c 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -712,7 +712,7 @@ def doClassCleanups(cls): function, args, kwargs = cls._class_cleanups.pop() try: function(*args, **kwargs) - except Exception as exc: + except Exception: cls.tearDown_exceptions.append(sys.exc_info()) def __call__(self, *args, **kwds): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 721c152179e99..ebc41184f83d5 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1778,7 +1778,7 @@ def retrieve(self, url, filename=None, reporthook=None, data=None): hdrs = fp.info() fp.close() return url2pathname(_splithost(url1)[1]), hdrs - except OSError as msg: + except OSError: pass fp = self.open(url, data) try: diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py index a0f5d40b2000c..17b75879ebaaf 100644 --- a/Lib/xml/sax/__init__.py +++ b/Lib/xml/sax/__init__.py @@ -78,7 +78,7 @@ def make_parser(parser_list=()): for parser_name in list(parser_list) + default_parser_list: try: return _create_parser(parser_name) - except ImportError as e: + except ImportError: import sys if parser_name in sys.modules: # The parser module was found, but importing it From webhook-mailer at python.org Tue Nov 19 18:13:10 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 19 Nov 2019 23:13:10 -0000 Subject: [Python-checkins] bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) Message-ID: https://github.com/python/cpython/commit/ac2235432c607ce2c0faf6dff5d9b2534d2f6652 commit: ac2235432c607ce2c0faf6dff5d9b2534d2f6652 branch: master author: Brandt Bucher committer: Victor Stinner date: 2019-11-20T00:13:05+01:00 summary: bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) files: M Modules/faulthandler.c diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 129a104dba3f3..d1280532ae2d4 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1334,25 +1334,36 @@ PyInit_faulthandler(void) #ifdef MS_WINDOWS /* RaiseException() codes (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", - EXCEPTION_ACCESS_VIOLATION)) - return NULL; + EXCEPTION_ACCESS_VIOLATION)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", - EXCEPTION_INT_DIVIDE_BY_ZERO)) - return NULL; + EXCEPTION_INT_DIVIDE_BY_ZERO)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", - EXCEPTION_STACK_OVERFLOW)) - return NULL; + EXCEPTION_STACK_OVERFLOW)) { + goto error; + } /* RaiseException() flags (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", - EXCEPTION_NONCONTINUABLE)) - return NULL; + EXCEPTION_NONCONTINUABLE)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", - EXCEPTION_NONCONTINUABLE_EXCEPTION)) - return NULL; + EXCEPTION_NONCONTINUABLE_EXCEPTION)) { + goto error; + } #endif return m; + +#ifdef MS_WINDOWS +error: + Py_DECREF(m); + return NULL; +#endif } static int From webhook-mailer at python.org Tue Nov 19 18:30:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 23:30:14 -0000 Subject: [Python-checkins] bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) Message-ID: https://github.com/python/cpython/commit/5bd2af9c79796aa03b06d1e35ab6df7e28364e24 commit: 5bd2af9c79796aa03b06d1e35ab6df7e28364e24 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T15:30:02-08:00 summary: bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) (cherry picked from commit ac2235432c607ce2c0faf6dff5d9b2534d2f6652) Co-authored-by: Brandt Bucher files: M Modules/faulthandler.c diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 97c64f633091f..e72faab32aa85 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1273,25 +1273,36 @@ PyInit_faulthandler(void) #ifdef MS_WINDOWS /* RaiseException() codes (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", - EXCEPTION_ACCESS_VIOLATION)) - return NULL; + EXCEPTION_ACCESS_VIOLATION)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", - EXCEPTION_INT_DIVIDE_BY_ZERO)) - return NULL; + EXCEPTION_INT_DIVIDE_BY_ZERO)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", - EXCEPTION_STACK_OVERFLOW)) - return NULL; + EXCEPTION_STACK_OVERFLOW)) { + goto error; + } /* RaiseException() flags (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", - EXCEPTION_NONCONTINUABLE)) - return NULL; + EXCEPTION_NONCONTINUABLE)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", - EXCEPTION_NONCONTINUABLE_EXCEPTION)) - return NULL; + EXCEPTION_NONCONTINUABLE_EXCEPTION)) { + goto error; + } #endif return m; + +#ifdef MS_WINDOWS +error: + Py_DECREF(m); + return NULL; +#endif } static int From webhook-mailer at python.org Tue Nov 19 18:31:13 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 19 Nov 2019 23:31:13 -0000 Subject: [Python-checkins] bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) Message-ID: https://github.com/python/cpython/commit/a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10 commit: a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T15:31:08-08:00 summary: bpo-38823: Fix refleaks in faulthandler init error path on Windows (GH-17250) (cherry picked from commit ac2235432c607ce2c0faf6dff5d9b2534d2f6652) Co-authored-by: Brandt Bucher files: M Modules/faulthandler.c diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 7b325996b268b..251d8e08a208e 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1276,25 +1276,36 @@ PyInit_faulthandler(void) #ifdef MS_WINDOWS /* RaiseException() codes (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_ACCESS_VIOLATION", - EXCEPTION_ACCESS_VIOLATION)) - return NULL; + EXCEPTION_ACCESS_VIOLATION)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_INT_DIVIDE_BY_ZERO", - EXCEPTION_INT_DIVIDE_BY_ZERO)) - return NULL; + EXCEPTION_INT_DIVIDE_BY_ZERO)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_STACK_OVERFLOW", - EXCEPTION_STACK_OVERFLOW)) - return NULL; + EXCEPTION_STACK_OVERFLOW)) { + goto error; + } /* RaiseException() flags (prefixed by an underscore) */ if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE", - EXCEPTION_NONCONTINUABLE)) - return NULL; + EXCEPTION_NONCONTINUABLE)) { + goto error; + } if (PyModule_AddIntConstant(m, "_EXCEPTION_NONCONTINUABLE_EXCEPTION", - EXCEPTION_NONCONTINUABLE_EXCEPTION)) - return NULL; + EXCEPTION_NONCONTINUABLE_EXCEPTION)) { + goto error; + } #endif return m; + +#ifdef MS_WINDOWS +error: + Py_DECREF(m); + return NULL; +#endif } static int From webhook-mailer at python.org Tue Nov 19 18:38:22 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Tue, 19 Nov 2019 23:38:22 -0000 Subject: [Python-checkins] bpo-38858: Reorganize pycore_init_types() (GH-17265) Message-ID: https://github.com/python/cpython/commit/ef5aa9af7c7e493402ac62009e4400aed7c3d54e commit: ef5aa9af7c7e493402ac62009e4400aed7c3d54e branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T00:38:03+01:00 summary: bpo-38858: Reorganize pycore_init_types() (GH-17265) * Call _PyLong_Init() and _PyExc_Init() earlier * new_interpreter() reuses pycore_init_types() files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index add7519ed0f70..1bfc7c16dc67c 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -565,19 +565,15 @@ pycore_init_types(void) return status; } + if (!_PyLong_Init()) { + return _PyStatus_ERR("can't init longs"); + } + status = _PyUnicode_Init(); if (_PyStatus_EXCEPTION(status)) { return status; } - if (_PyStructSequence_Init() < 0) { - return _PyStatus_ERR("can't initialize structseq"); - } - - if (!_PyLong_Init()) { - return _PyStatus_ERR("can't init longs"); - } - status = _PyExc_Init(); if (_PyStatus_EXCEPTION(status)) { return status; @@ -587,8 +583,8 @@ pycore_init_types(void) return _PyStatus_ERR("can't init float"); } - if (!_PyContext_Init()) { - return _PyStatus_ERR("can't init context"); + if (_PyStructSequence_Init() < 0) { + return _PyStatus_ERR("can't initialize structseq"); } status = _PyErr_Init(); @@ -596,6 +592,10 @@ pycore_init_types(void) return status; } + if (!_PyContext_Init()) { + return _PyStatus_ERR("can't init context"); + } + return _PyStatus_OK(); } @@ -1447,16 +1447,7 @@ new_interpreter(PyThreadState **tstate_p) } config = &interp->config; - status = _PyExc_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyErr_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - + status = pycore_init_types(); /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); From webhook-mailer at python.org Tue Nov 19 18:46:58 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Tue, 19 Nov 2019 23:46:58 -0000 Subject: [Python-checkins] bpo-37957: Allow regrtest to receive a file with test (and subtests) to ignore (GH-16989) Message-ID: https://github.com/python/cpython/commit/e0cd8aa70a3ce19c3d3712568940aa0cbd9aa97b commit: e0cd8aa70a3ce19c3d3712568940aa0cbd9aa97b branch: master author: Pablo Galindo committer: GitHub date: 2019-11-19T23:46:49Z summary: bpo-37957: Allow regrtest to receive a file with test (and subtests) to ignore (GH-16989) When building Python in some uncommon platforms there are some known tests that will fail. Right now, the test suite has the ability to ignore entire tests using the -x option and to receive a filter file using the --matchfile filter. The problem with the --matchfile option is that it receives a file with patterns to accept and when you want to ignore a couple of tests and subtests, is too cumbersome to lists ALL tests that are not the ones that you want to accept and he problem with -x is that is not easy to ignore just a subtests that fail and the whole test needs to be ignored. For these reasons, add a new option to allow to ignore a list of test and subtests for these situations. files: A Misc/NEWS.d/next/Tests/2019-10-30-00-01-43.bpo-37957.X1r78F.rst M Lib/test/libregrtest/cmdline.py M Lib/test/libregrtest/main.py M Lib/test/libregrtest/runtest.py M Lib/test/support/__init__.py M Lib/test/test_regrtest.py M Lib/test/test_support.py diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index c8fedc7ad329b..c0bb051bd0783 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -207,10 +207,17 @@ def _create_parser(): group.add_argument('-m', '--match', metavar='PAT', dest='match_tests', action='append', help='match test cases and methods with glob pattern PAT') + group.add_argument('-i', '--ignore', metavar='PAT', + dest='ignore_tests', action='append', + help='ignore test cases and methods with glob pattern PAT') group.add_argument('--matchfile', metavar='FILENAME', dest='match_filename', help='similar to --match but get patterns from a ' 'text file, one pattern per line') + group.add_argument('--ignorefile', metavar='FILENAME', + dest='ignore_filename', + help='similar to --matchfile but it receives patterns ' + 'from text file to ignore') group.add_argument('-G', '--failfast', action='store_true', help='fail as soon as a test fails (only with -v or -W)') group.add_argument('-u', '--use', metavar='RES1,RES2,...', @@ -317,7 +324,8 @@ def _parse_args(args, **kwargs): findleaks=1, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, random_seed=None, use_mp=None, verbose3=False, forever=False, - header=False, failfast=False, match_tests=None, pgo=False) + header=False, failfast=False, match_tests=None, ignore_tests=None, + pgo=False) for k, v in kwargs.items(): if not hasattr(ns, k): raise TypeError('%r is an invalid keyword argument ' @@ -395,6 +403,12 @@ def _parse_args(args, **kwargs): with open(ns.match_filename) as fp: for line in fp: ns.match_tests.append(line.strip()) + if ns.ignore_filename: + if ns.ignore_tests is None: + ns.ignore_tests = [] + with open(ns.ignore_filename) as fp: + for line in fp: + ns.ignore_tests.append(line.strip()) if ns.forever: # --forever implies --failfast ns.failfast = True diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 76ad3359f2d7a..1de51b740a98c 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -287,7 +287,7 @@ def _list_cases(self, suite): def list_cases(self): support.verbose = False - support.set_match_tests(self.ns.match_tests) + support.set_match_tests(self.ns.match_tests, self.ns.ignore_tests) for test_name in self.selected: abstest = get_abs_module(self.ns, test_name) diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index eeb108bb44739..558f2099c66f5 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -123,7 +123,7 @@ def _runtest(ns, test_name): start_time = time.perf_counter() try: - support.set_match_tests(ns.match_tests) + support.set_match_tests(ns.match_tests, ns.ignore_tests) support.junit_xml_list = xml_list = [] if ns.xmlpath else None if ns.failfast: support.failfast = True diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 5ad32b8f4081c..7e1b30cc160ca 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2096,7 +2096,9 @@ def _run_suite(suite): # By default, don't filter tests _match_test_func = None -_match_test_patterns = None + +_accept_test_patterns = None +_ignore_test_patterns = None def match_test(test): @@ -2112,18 +2114,45 @@ def _is_full_match_test(pattern): # as a full test identifier. # Example: 'test.test_os.FileTests.test_access'. # - # Reject patterns which contain fnmatch patterns: '*', '?', '[...]' - # or '[!...]'. For example, reject 'test_access*'. + # ignore patterns which contain fnmatch patterns: '*', '?', '[...]' + # or '[!...]'. For example, ignore 'test_access*'. return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) -def set_match_tests(patterns): - global _match_test_func, _match_test_patterns +def set_match_tests(accept_patterns=None, ignore_patterns=None): + global _match_test_func, _accept_test_patterns, _ignore_test_patterns - if patterns == _match_test_patterns: - # No change: no need to recompile patterns. - return + if accept_patterns is None: + accept_patterns = () + if ignore_patterns is None: + ignore_patterns = () + + accept_func = ignore_func = None + + if accept_patterns != _accept_test_patterns: + accept_patterns, accept_func = _compile_match_function(accept_patterns) + if ignore_patterns != _ignore_test_patterns: + ignore_patterns, ignore_func = _compile_match_function(ignore_patterns) + + # Create a copy since patterns can be mutable and so modified later + _accept_test_patterns = tuple(accept_patterns) + _ignore_test_patterns = tuple(ignore_patterns) + + if accept_func is not None or ignore_func is not None: + def match_function(test_id): + accept = True + ignore = False + if accept_func: + accept = accept_func(test_id) + if ignore_func: + ignore = ignore_func(test_id) + return accept and not ignore + + _match_test_func = match_function + + +def _compile_match_function(patterns): if not patterns: func = None # set_match_tests(None) behaves as set_match_tests(()) @@ -2151,10 +2180,7 @@ def match_test_regex(test_id): func = match_test_regex - # Create a copy since patterns can be mutable and so modified later - _match_test_patterns = tuple(patterns) - _match_test_func = func - + return patterns, func def run_unittest(*classes): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 5df78861db9ce..93f8d44ec6938 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -155,6 +155,24 @@ def test_single(self): self.assertTrue(ns.single) self.checkError([opt, '-f', 'foo'], "don't go together") + def test_ignore(self): + for opt in '-i', '--ignore': + with self.subTest(opt=opt): + ns = libregrtest._parse_args([opt, 'pattern']) + self.assertEqual(ns.ignore_tests, ['pattern']) + self.checkError([opt], 'expected one argument') + + self.addCleanup(support.unlink, support.TESTFN) + with open(support.TESTFN, "w") as fp: + print('matchfile1', file=fp) + print('matchfile2', file=fp) + + filename = os.path.abspath(support.TESTFN) + ns = libregrtest._parse_args(['-m', 'match', + '--ignorefile', filename]) + self.assertEqual(ns.ignore_tests, + ['matchfile1', 'matchfile2']) + def test_match(self): for opt in '-m', '--match': with self.subTest(opt=opt): @@ -961,6 +979,42 @@ def parse_methods(self, output): regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) return [match.group(1) for match in regex.finditer(output)] + def test_ignorefile(self): + code = textwrap.dedent(""" + import unittest + + class Tests(unittest.TestCase): + def test_method1(self): + pass + def test_method2(self): + pass + def test_method3(self): + pass + def test_method4(self): + pass + """) + all_methods = ['test_method1', 'test_method2', + 'test_method3', 'test_method4'] + testname = self.create_test(code=code) + + # only run a subset + filename = support.TESTFN + self.addCleanup(support.unlink, filename) + + subset = [ + # only ignore the method name + 'test_method1', + # ignore the full identifier + '%s.Tests.test_method3' % testname] + with open(filename, "w") as fp: + for name in subset: + print(name, file=fp) + + output = self.run_tests("-v", "--ignorefile", filename, testname) + methods = self.parse_methods(output) + subset = ['test_method2', 'test_method4'] + self.assertEqual(methods, subset) + def test_matchfile(self): code = textwrap.dedent(""" import unittest diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 8f0746aed8299..e3ce670b8437f 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -527,6 +527,7 @@ def id(self): test_access = Test('test.test_os.FileTests.test_access') test_chdir = Test('test.test_os.Win32ErrorTests.test_chdir') + # Test acceptance with support.swap_attr(support, '_match_test_func', None): # match all support.set_match_tests([]) @@ -534,45 +535,92 @@ def id(self): self.assertTrue(support.match_test(test_chdir)) # match all using None - support.set_match_tests(None) + support.set_match_tests(None, None) self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) # match the full test identifier - support.set_match_tests([test_access.id()]) + support.set_match_tests([test_access.id()], None) self.assertTrue(support.match_test(test_access)) self.assertFalse(support.match_test(test_chdir)) # match the module name - support.set_match_tests(['test_os']) + support.set_match_tests(['test_os'], None) self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) # Test '*' pattern - support.set_match_tests(['test_*']) + support.set_match_tests(['test_*'], None) self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) # Test case sensitivity - support.set_match_tests(['filetests']) + support.set_match_tests(['filetests'], None) self.assertFalse(support.match_test(test_access)) - support.set_match_tests(['FileTests']) + support.set_match_tests(['FileTests'], None) self.assertTrue(support.match_test(test_access)) # Test pattern containing '.' and a '*' metacharacter - support.set_match_tests(['*test_os.*.test_*']) + support.set_match_tests(['*test_os.*.test_*'], None) self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) # Multiple patterns - support.set_match_tests([test_access.id(), test_chdir.id()]) + support.set_match_tests([test_access.id(), test_chdir.id()], None) self.assertTrue(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) - support.set_match_tests(['test_access', 'DONTMATCH']) + support.set_match_tests(['test_access', 'DONTMATCH'], None) self.assertTrue(support.match_test(test_access)) self.assertFalse(support.match_test(test_chdir)) + # Test rejection + with support.swap_attr(support, '_match_test_func', None): + # match all + support.set_match_tests(ignore_patterns=[]) + self.assertTrue(support.match_test(test_access)) + self.assertTrue(support.match_test(test_chdir)) + + # match all using None + support.set_match_tests(None, None) + self.assertTrue(support.match_test(test_access)) + self.assertTrue(support.match_test(test_chdir)) + + # match the full test identifier + support.set_match_tests(None, [test_access.id()]) + self.assertFalse(support.match_test(test_access)) + self.assertTrue(support.match_test(test_chdir)) + + # match the module name + support.set_match_tests(None, ['test_os']) + self.assertFalse(support.match_test(test_access)) + self.assertFalse(support.match_test(test_chdir)) + + # Test '*' pattern + support.set_match_tests(None, ['test_*']) + self.assertFalse(support.match_test(test_access)) + self.assertFalse(support.match_test(test_chdir)) + + # Test case sensitivity + support.set_match_tests(None, ['filetests']) + self.assertTrue(support.match_test(test_access)) + support.set_match_tests(None, ['FileTests']) + self.assertFalse(support.match_test(test_access)) + + # Test pattern containing '.' and a '*' metacharacter + support.set_match_tests(None, ['*test_os.*.test_*']) + self.assertFalse(support.match_test(test_access)) + self.assertFalse(support.match_test(test_chdir)) + + # Multiple patterns + support.set_match_tests(None, [test_access.id(), test_chdir.id()]) + self.assertFalse(support.match_test(test_access)) + self.assertFalse(support.match_test(test_chdir)) + + support.set_match_tests(None, ['test_access', 'DONTMATCH']) + self.assertFalse(support.match_test(test_access)) + self.assertTrue(support.match_test(test_chdir)) + def test_fd_count(self): # We cannot test the absolute value of fd_count(): on old Linux # kernel or glibc versions, os.urandom() keeps a FD open on diff --git a/Misc/NEWS.d/next/Tests/2019-10-30-00-01-43.bpo-37957.X1r78F.rst b/Misc/NEWS.d/next/Tests/2019-10-30-00-01-43.bpo-37957.X1r78F.rst new file mode 100644 index 0000000000000..75e186ef33e07 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-10-30-00-01-43.bpo-37957.X1r78F.rst @@ -0,0 +1,3 @@ +test.regrtest now can receive a list of test patterns to ignore (using the +-i/--ignore argument) or a file with a list of patterns to ignore (using the +--ignore-file argument). Patch by Pablo Galindo. From webhook-mailer at python.org Tue Nov 19 19:18:15 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 00:18:15 -0000 Subject: [Python-checkins] bpo-38631: Avoid Py_FatalError() in handle_legacy_finalizers() (GH-17266) Message-ID: https://github.com/python/cpython/commit/444b39bb64aa894d3f1831210a8ce40042a5a532 commit: 444b39bb64aa894d3f1831210a8ce40042a5a532 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T01:18:11+01:00 summary: bpo-38631: Avoid Py_FatalError() in handle_legacy_finalizers() (GH-17266) * Rename _PyGC_Initialize() to _PyGC_InitializeRuntime() * Add _PyGC_Init(): initialize _PyRuntime.gc.garbage list * Call _PyGC_Init() before _PyTypes_Init() files: M Include/internal/pycore_pylifecycle.h M Include/internal/pycore_pymem.h M Modules/gcmodule.c M Python/pylifecycle.c M Python/pystate.c diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index d89dbeacb240b..16baf10061b4b 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -57,6 +57,7 @@ extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _PyTypes_Init(void); extern PyStatus _PyImportZip_Init(PyThreadState *tstate); +extern PyStatus _PyGC_Init(struct pyruntimestate *runtime); /* Various internal finalizers */ diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 535f99e8cc52e..97d8fd99904a7 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -144,7 +144,7 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; -PyAPI_FUNC(void) _PyGC_Initialize(struct _gc_runtime_state *); +PyAPI_FUNC(void) _PyGC_InitializeRuntime(struct _gc_runtime_state *); /* Set the memory allocator of the specified domain to the default. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index cb7a3de57a326..d2e39371b9e8c 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -25,6 +25,7 @@ #include "Python.h" #include "pycore_context.h" +#include "pycore_initconfig.h" #include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" @@ -129,7 +130,7 @@ static PyObject *gc_str = NULL; #define GEN_HEAD(state, n) (&(state)->generations[n].head) void -_PyGC_Initialize(struct _gc_runtime_state *state) +_PyGC_InitializeRuntime(struct _gc_runtime_state *state) { state->enabled = 1; /* automatic collection enabled? */ @@ -151,6 +152,21 @@ _PyGC_Initialize(struct _gc_runtime_state *state) state->permanent_generation = permanent_generation; } + +PyStatus +_PyGC_Init(_PyRuntimeState *runtime) +{ + struct _gc_runtime_state *state = &runtime->gc; + if (state->garbage == NULL) { + state->garbage = PyList_New(0); + if (state->garbage == NULL) { + return _PyStatus_NO_MEMORY(); + } + } + return _PyStatus_OK(); +} + + /* _gc_prev values --------------- @@ -905,13 +921,9 @@ handle_legacy_finalizers(struct _gc_runtime_state *state, PyGC_Head *finalizers, PyGC_Head *old) { assert(!PyErr_Occurred()); + assert(state->garbage != NULL); PyGC_Head *gc = GC_NEXT(finalizers); - if (state->garbage == NULL) { - state->garbage = PyList_New(0); - if (state->garbage == NULL) - Py_FatalError("gc couldn't create gc.garbage list"); - } for (; gc != finalizers; gc = GC_NEXT(gc)) { PyObject *op = FROM_GC(gc); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1bfc7c16dc67c..9739bb154181f 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -558,9 +558,16 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_types(void) +pycore_init_types(_PyRuntimeState *runtime) { - PyStatus status = _PyTypes_Init(); + PyStatus status; + + status = _PyGC_Init(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyTypes_Init(); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -683,7 +690,7 @@ pyinit_config(_PyRuntimeState *runtime, config = &tstate->interp->config; *tstate_p = tstate; - status = pycore_init_types(); + status = pycore_init_types(runtime); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1447,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p) } config = &interp->config; - status = pycore_init_types(); + status = pycore_init_types(runtime); /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); diff --git a/Python/pystate.c b/Python/pystate.c index b4b12472286a3..06cc9a8fb446e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -58,7 +58,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) runtime->open_code_userdata = open_code_userdata; runtime->audit_hook_head = audit_hook_head; - _PyGC_Initialize(&runtime->gc); + _PyGC_InitializeRuntime(&runtime->gc); _PyEval_Initialize(&runtime->ceval); PyPreConfig_InitPythonConfig(&runtime->preconfig); From webhook-mailer at python.org Tue Nov 19 19:30:47 2019 From: webhook-mailer at python.org (Lisa Roach) Date: Wed, 20 Nov 2019 00:30:47 -0000 Subject: [Python-checkins] bpo-38753: AsyncMock added in version 3.8 (GH-17102) Message-ID: https://github.com/python/cpython/commit/279d8df5e5e8bbd4429420649359f7afcb4c8cce commit: 279d8df5e5e8bbd4429420649359f7afcb4c8cce branch: master author: John Belmonte committer: Lisa Roach date: 2019-11-19T16:30:43-08:00 summary: bpo-38753: AsyncMock added in version 3.8 (GH-17102) files: M Doc/library/unittest.mock.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 746cf765b077f..7faecff84f63f 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -915,6 +915,7 @@ object:: >>> mock.async_foo + .. versionadded:: 3.8 .. method:: assert_awaited() From webhook-mailer at python.org Tue Nov 19 19:49:36 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 00:49:36 -0000 Subject: [Python-checkins] bpo-36710: Pass tstate parameter to GC collect() (GH-17267) Message-ID: https://github.com/python/cpython/commit/2e96906da764402b4c8062dbf99171ca506f9e12 commit: 2e96906da764402b4c8062dbf99171ca506f9e12 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T01:49:32+01:00 summary: bpo-36710: Pass tstate parameter to GC collect() (GH-17267) Pass tstate parameter (PyThreadState) to GC collect() function and other GC subfunctions. files: M Modules/gcmodule.c diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index d2e39371b9e8c..78f6631866ac4 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -27,6 +27,7 @@ #include "pycore_context.h" #include "pycore_initconfig.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "frameobject.h" /* for PyFrame_ClearFreeList */ @@ -917,10 +918,11 @@ debug_cycle(const char *msg, PyObject *op) * merged into the old list regardless. */ static void -handle_legacy_finalizers(struct _gc_runtime_state *state, +handle_legacy_finalizers(PyThreadState *tstate, + struct _gc_runtime_state *state, PyGC_Head *finalizers, PyGC_Head *old) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); assert(state->garbage != NULL); PyGC_Head *gc = GC_NEXT(finalizers); @@ -929,7 +931,7 @@ handle_legacy_finalizers(struct _gc_runtime_state *state, if ((state->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { if (PyList_Append(state->garbage, op) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); break; } } @@ -979,10 +981,10 @@ finalize_garbage(PyGC_Head *collectable) * objects may be freed. It is possible I screwed something up here. */ static void -delete_garbage(struct _gc_runtime_state *state, +delete_garbage(PyThreadState *tstate, struct _gc_runtime_state *state, PyGC_Head *collectable, PyGC_Head *old) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); while (!gc_list_is_empty(collectable)) { PyGC_Head *gc = GC_NEXT(collectable); @@ -994,7 +996,7 @@ delete_garbage(struct _gc_runtime_state *state, if (state->debug & DEBUG_SAVEALL) { assert(state->garbage != NULL); if (PyList_Append(state->garbage, op) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } else { @@ -1002,7 +1004,7 @@ delete_garbage(struct _gc_runtime_state *state, if ((clear = Py_TYPE(op)->tp_clear) != NULL) { Py_INCREF(op); (void) clear(op); - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { _PyErr_WriteUnraisableMsg("in tp_clear of", (PyObject*)Py_TYPE(op)); } @@ -1143,7 +1145,7 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t -collect(struct _gc_runtime_state *state, int generation, +collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) { int i; @@ -1245,7 +1247,7 @@ collect(struct _gc_runtime_state *state, int generation, * in finalizers to be freed. */ m += gc_list_size(&final_unreachable); - delete_garbage(state, &final_unreachable, old); + delete_garbage(tstate, state, &final_unreachable, old); /* Collect statistics on uncollectable objects found and print * debugging information. */ @@ -1266,7 +1268,7 @@ collect(struct _gc_runtime_state *state, int generation, * reachable list of garbage. The programmer has to deal with * this if they insist on creating this type of structure. */ - handle_legacy_finalizers(state, &finalizers, old); + handle_legacy_finalizers(tstate, state, &finalizers, old); validate_list(old, collecting_clear_unreachable_clear); /* Clear free list only during the collection of the highest @@ -1275,9 +1277,9 @@ collect(struct _gc_runtime_state *state, int generation, clear_freelists(); } - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { if (nofail) { - PyErr_Clear(); + _PyErr_Clear(tstate); } else { if (gc_str == NULL) @@ -1301,11 +1303,11 @@ collect(struct _gc_runtime_state *state, int generation, stats->uncollectable += n; if (PyDTrace_GC_DONE_ENABLED()) { - PyDTrace_GC_DONE(n+m); + PyDTrace_GC_DONE(n + m); } - assert(!PyErr_Occurred()); - return n+m; + assert(!_PyErr_Occurred(tstate)); + return n + m; } /* Invoke progress callbacks to notify clients that garbage collection @@ -1356,19 +1358,20 @@ invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, * progress callbacks. */ static Py_ssize_t -collect_with_callback(struct _gc_runtime_state *state, int generation) +collect_with_callback(PyThreadState *tstate, struct _gc_runtime_state *state, + int generation) { assert(!PyErr_Occurred()); Py_ssize_t result, collected, uncollectable; invoke_gc_callback(state, "start", generation, 0, 0); - result = collect(state, generation, &collected, &uncollectable, 0); + result = collect(tstate, state, generation, &collected, &uncollectable, 0); invoke_gc_callback(state, "stop", generation, collected, uncollectable); assert(!PyErr_Occurred()); return result; } static Py_ssize_t -collect_generations(struct _gc_runtime_state *state) +collect_generations(PyThreadState *tstate, struct _gc_runtime_state *state) { /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and @@ -1383,7 +1386,7 @@ collect_generations(struct _gc_runtime_state *state) if (i == NUM_GENERATIONS - 1 && state->long_lived_pending < state->long_lived_total / 4) continue; - n = collect_with_callback(state, i); + n = collect_with_callback(tstate, state, i); break; } } @@ -1451,9 +1454,10 @@ static Py_ssize_t gc_collect_impl(PyObject *module, int generation) /*[clinic end generated code: output=b697e633043233c7 input=40720128b682d879]*/ { + PyThreadState *tstate = _PyThreadState_GET(); if (generation < 0 || generation >= NUM_GENERATIONS) { - PyErr_SetString(PyExc_ValueError, "invalid generation"); + _PyErr_SetString(tstate, PyExc_ValueError, "invalid generation"); return -1; } @@ -1465,7 +1469,7 @@ gc_collect_impl(PyObject *module, int generation) } else { state->collecting = 1; - n = collect_with_callback(state, generation); + n = collect_with_callback(tstate, state, generation); state->collecting = 0; } return n; @@ -1940,7 +1944,9 @@ PyInit_gc(void) Py_ssize_t PyGC_Collect(void) { + PyThreadState *tstate = _PyThreadState_GET(); struct _gc_runtime_state *state = &_PyRuntime.gc; + if (!state->enabled) { return 0; } @@ -1953,9 +1959,9 @@ PyGC_Collect(void) else { PyObject *exc, *value, *tb; state->collecting = 1; - PyErr_Fetch(&exc, &value, &tb); - n = collect_with_callback(state, NUM_GENERATIONS - 1); - PyErr_Restore(exc, value, tb); + _PyErr_Fetch(tstate, &exc, &value, &tb); + n = collect_with_callback(tstate, state, NUM_GENERATIONS - 1); + _PyErr_Restore(tstate, exc, value, tb); state->collecting = 0; } @@ -1971,7 +1977,8 @@ _PyGC_CollectIfEnabled(void) Py_ssize_t _PyGC_CollectNoFail(void) { - assert(!PyErr_Occurred()); + PyThreadState *tstate = _PyThreadState_GET(); + assert(!_PyErr_Occurred(tstate)); struct _gc_runtime_state *state = &_PyRuntime.gc; Py_ssize_t n; @@ -1987,7 +1994,7 @@ _PyGC_CollectNoFail(void) } else { state->collecting = 1; - n = collect(state, NUM_GENERATIONS - 1, NULL, NULL, 1); + n = collect(tstate, state, NUM_GENERATIONS - 1, NULL, NULL, 1); state->collecting = 0; } return n; @@ -2098,19 +2105,23 @@ static PyObject * _PyObject_GC_Alloc(int use_calloc, size_t basicsize) { struct _gc_runtime_state *state = &_PyRuntime.gc; - PyObject *op; - PyGC_Head *g; - size_t size; - if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) + if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return PyErr_NoMemory(); - size = sizeof(PyGC_Head) + basicsize; - if (use_calloc) + } + size_t size = sizeof(PyGC_Head) + basicsize; + + PyGC_Head *g; + if (use_calloc) { g = (PyGC_Head *)PyObject_Calloc(1, size); - else + } + else { g = (PyGC_Head *)PyObject_Malloc(size); - if (g == NULL) + } + if (g == NULL) { return PyErr_NoMemory(); + } assert(((uintptr_t)g & 3) == 0); // g must be aligned 4bytes boundary + g->_gc_next = 0; g->_gc_prev = 0; state->generations[0].count++; /* number of allocated GC objects */ @@ -2118,12 +2129,14 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) state->enabled && state->generations[0].threshold && !state->collecting && - !PyErr_Occurred()) { + !PyErr_Occurred()) + { + PyThreadState *tstate = _PyThreadState_GET(); state->collecting = 1; - collect_generations(state); + collect_generations(tstate, state); state->collecting = 0; } - op = FROM_GC(g); + PyObject *op = FROM_GC(g); return op; } From webhook-mailer at python.org Tue Nov 19 19:59:41 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 00:59:41 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in marshal init error path (GH-17260) Message-ID: https://github.com/python/cpython/commit/33b671e72450bf4b5a946ce0dde6b7fe21150108 commit: 33b671e72450bf4b5a946ce0dde6b7fe21150108 branch: master author: Brandt Bucher committer: Victor Stinner date: 2019-11-20T01:59:32+01:00 summary: bpo-38823: Fix refleak in marshal init error path (GH-17260) files: M Python/marshal.c diff --git a/Python/marshal.c b/Python/marshal.c index cb11c8c74ef3a..ec6b3dadc02ca 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1829,6 +1829,9 @@ PyMarshal_Init(void) PyObject *mod = PyModule_Create(&marshalmodule); if (mod == NULL) return NULL; - PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + Py_DECREF(mod); + return NULL; + } return mod; } From webhook-mailer at python.org Tue Nov 19 20:28:11 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 01:28:11 -0000 Subject: [Python-checkins] bpo-36710: Add PyInterpreterState.runtime field (GH-17270) Message-ID: https://github.com/python/cpython/commit/01b1cc12e7c6a3d6a3d27ba7c731687d57aae92a commit: 01b1cc12e7c6a3d6a3d27ba7c731687d57aae92a branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T02:27:56+01:00 summary: bpo-36710: Add PyInterpreterState.runtime field (GH-17270) Add PyInterpreterState.runtime field: reference to the _PyRuntime global variable. This field exists to not have to pass runtime in addition to tstate to a function. Get runtime from tstate: tstate->interp->runtime. Remove "_PyRuntimeState *runtime" parameter from functions already taking a "PyThreadState *tstate" parameter. _PyGC_Init() first parameter becomes "PyThreadState *tstate". files: M Include/internal/pycore_pylifecycle.h M Include/internal/pycore_pystate.h M Modules/_threadmodule.c M Modules/gcmodule.c M Python/ceval.c M Python/pylifecycle.c M Python/pystate.c M Python/sysmodule.c diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 16baf10061b4b..f269ffe786893 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -38,15 +38,12 @@ extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(PyThreadState *tstate); extern PyStatus _PySys_Create( - struct pyruntimestate *runtime, PyThreadState *tstate, PyObject **sysmod_p); extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); -extern int _PySys_InitMain( - struct pyruntimestate *runtime, - PyThreadState *tstate); +extern int _PySys_InitMain(PyThreadState *tstate); extern PyStatus _PyImport_Init(PyThreadState *tstate); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); @@ -57,7 +54,7 @@ extern PyStatus _Py_HashRandomization_Init(const PyConfig *); extern PyStatus _PyTypes_Init(void); extern PyStatus _PyImportZip_Init(PyThreadState *tstate); -extern PyStatus _PyGC_Init(struct pyruntimestate *runtime); +extern PyStatus _PyGC_Init(PyThreadState *tstate); /* Various internal finalizers */ @@ -89,9 +86,7 @@ extern void _PyHash_Fini(void); extern void _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyGILState_Init( - struct pyruntimestate *runtime, - PyThreadState *tstate); +extern void _PyGILState_Init(PyThreadState *tstate); extern void _PyGILState_Fini(struct pyruntimestate *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index eb44ae93fc4c4..fec64a7badba1 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -62,6 +62,11 @@ struct _is { struct _is *next; struct _ts *tstate_head; + /* Reference to the _PyRuntime global variable. This field exists + to not have to pass runtime in addition to tstate to a function. + Get runtime from tstate: tstate->interp->runtime. */ + struct pyruntimestate *runtime; + int64_t id; int64_t id_refcount; int requires_idref; @@ -301,7 +306,6 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); /* Other */ PyAPI_FUNC(void) _PyThreadState_Init( - _PyRuntimeState *runtime, PyThreadState *tstate); PyAPI_FUNC(void) _PyThreadState_DeleteExcept( _PyRuntimeState *runtime, diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 1c7df3f874147..befd213bfebaa 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1007,7 +1007,7 @@ t_bootstrap(void *boot_raw) runtime = boot->runtime; tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); - _PyThreadState_Init(runtime, tstate); + _PyThreadState_Init(tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; res = PyObject_Call(boot->func, boot->args, boot->keyw); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 78f6631866ac4..05ca026189b67 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -155,9 +155,9 @@ _PyGC_InitializeRuntime(struct _gc_runtime_state *state) PyStatus -_PyGC_Init(_PyRuntimeState *runtime) +_PyGC_Init(PyThreadState *tstate) { - struct _gc_runtime_state *state = &runtime->gc; + struct _gc_runtime_state *state = &tstate->interp->runtime->gc; if (state->garbage == NULL) { state->garbage = PyList_New(0); if (state->garbage == NULL) { diff --git a/Python/ceval.c b/Python/ceval.c index 9f4b43615e28f..ee13fd1ad7043 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -191,7 +191,8 @@ static size_t opcache_global_misses = 0; int PyEval_ThreadsInitialized(void) { - return gil_created(&_PyRuntime.ceval.gil); + _PyRuntimeState *runtime = &_PyRuntime; + return gil_created(&runtime->ceval.gil); } void @@ -235,8 +236,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) } static inline void -exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) +exit_thread_if_finalizing(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; /* _Py_Finalizing is protected by the GIL */ if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { drop_gil(&runtime->ceval, tstate); @@ -283,7 +285,7 @@ PyEval_AcquireLock(void) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); } void @@ -305,13 +307,13 @@ PyEval_AcquireThread(PyThreadState *tstate) Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; struct _ceval_runtime_state *ceval = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created(&ceval->gil)); take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); } @@ -324,7 +326,7 @@ PyEval_ReleaseThread(PyThreadState *tstate) Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); @@ -384,7 +386,7 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; struct _ceval_runtime_state *ceval = &runtime->ceval; if (tstate == NULL) { @@ -394,7 +396,7 @@ PyEval_RestoreThread(PyThreadState *tstate) int err = errno; take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); errno = err; _PyThreadState_Swap(&runtime->gilstate, tstate); @@ -649,7 +651,8 @@ _PyEval_Initialize(struct _ceval_runtime_state *state) int Py_GetRecursionLimit(void) { - return _PyRuntime.ceval.recursion_limit; + struct _ceval_runtime_state *ceval = &_PyRuntime.ceval; + return ceval->recursion_limit; } void @@ -668,7 +671,7 @@ Py_SetRecursionLimit(int new_limit) int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; int recursion_limit = runtime->ceval.recursion_limit; #ifdef USE_STACKCHECK @@ -1245,7 +1248,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) take_gil(ceval, tstate); /* Check if we should make a quick exit. */ - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("ceval: orphan tstate"); @@ -4806,7 +4809,8 @@ _PyEval_GetAsyncGenFinalizer(void) static PyFrameObject * _PyEval_GetFrame(PyThreadState *tstate) { - return _PyRuntime.gilstate.getframe(tstate); + _PyRuntimeState *runtime = tstate->interp->runtime; + return runtime->gilstate.getframe(tstate); } PyFrameObject * diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 9739bb154181f..edff7f8f5e2a2 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -547,7 +547,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyEval_FiniThreads(&runtime->ceval); /* Auto-thread-state API */ - _PyGILState_Init(runtime, tstate); + _PyGILState_Init(tstate); /* Create the GIL */ PyEval_InitThreads(); @@ -558,11 +558,11 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_types(_PyRuntimeState *runtime) +pycore_init_types(PyThreadState *tstate) { PyStatus status; - status = _PyGC_Init(runtime); + status = _PyGC_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -690,13 +690,13 @@ pyinit_config(_PyRuntimeState *runtime, config = &tstate->interp->config; *tstate_p = tstate; - status = pycore_init_types(runtime); + status = pycore_init_types(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } PyObject *sysmod; - status = _PySys_Create(runtime, tstate, &sysmod); + status = _PySys_Create(tstate, &sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -915,8 +915,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static PyStatus -pyinit_main(_PyRuntimeState *runtime, PyThreadState *tstate) +pyinit_main(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; if (!runtime->core_initialized) { return _PyStatus_ERR("runtime core not initialized"); } @@ -943,7 +944,7 @@ pyinit_main(_PyRuntimeState *runtime, PyThreadState *tstate) return _PyStatus_ERR("can't initialize time"); } - if (_PySys_InitMain(runtime, tstate) < 0) { + if (_PySys_InitMain(tstate) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } @@ -1022,7 +1023,7 @@ _Py_InitializeMain(void) } _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return pyinit_main(runtime, tstate); + return pyinit_main(tstate); } @@ -1049,7 +1050,7 @@ Py_InitializeFromConfig(const PyConfig *config) config = &tstate->interp->config; if (config->_init_main) { - status = pyinit_main(runtime, tstate); + status = pyinit_main(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1454,7 +1455,7 @@ new_interpreter(PyThreadState **tstate_p) } config = &interp->config; - status = pycore_init_types(runtime); + status = pycore_init_types(tstate); /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); @@ -1471,7 +1472,7 @@ new_interpreter(PyThreadState **tstate_p) } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(runtime, tstate) < 0) { + if (_PySys_InitMain(tstate) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } } diff --git a/Python/pystate.c b/Python/pystate.c index 06cc9a8fb446e..99f93bb77c7b8 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,7 +39,6 @@ extern "C" { /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); -static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); static PyStatus @@ -205,6 +204,9 @@ PyInterpreterState_New(void) memset(interp, 0, sizeof(*interp)); interp->id_refcount = -1; + _PyRuntimeState *runtime = &_PyRuntime; + interp->runtime = runtime; + PyConfig_InitPythonConfig(&interp->config); interp->eval_frame = _PyEval_EvalFrameDefault; @@ -216,7 +218,6 @@ PyInterpreterState_New(void) #endif #endif - _PyRuntimeState *runtime = &_PyRuntime; struct pyinterpreters *interpreters = &runtime->interpreters; HEAD_LOCK(runtime); @@ -250,9 +251,11 @@ PyInterpreterState_New(void) } -static void -_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) +void +PyInterpreterState_Clear(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; + if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { PyErr_Clear(); } @@ -290,31 +293,25 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) // objects have been cleaned up at the point. } -void -PyInterpreterState_Clear(PyInterpreterState *interp) -{ - _PyInterpreterState_Clear(&_PyRuntime, interp); -} - static void -zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) +zapthreads(PyInterpreterState *interp) { PyThreadState *p; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ while ((p = interp->tstate_head) != NULL) { - _PyThreadState_Delete(runtime, p); + PyThreadState_Delete(p); } } -static void -_PyInterpreterState_Delete(_PyRuntimeState *runtime, - PyInterpreterState *interp) +void +PyInterpreterState_Delete(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(runtime, interp); + zapthreads(interp); HEAD_LOCK(runtime); PyInterpreterState **p; for (p = &interpreters->head; ; p = &(*p)->next) { @@ -343,13 +340,6 @@ _PyInterpreterState_Delete(_PyRuntimeState *runtime, } -void -PyInterpreterState_Delete(PyInterpreterState *interp) -{ - _PyInterpreterState_Delete(&_PyRuntime, interp); -} - - /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. @@ -376,8 +366,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) continue; } - _PyInterpreterState_Clear(runtime, interp); // XXX must activate? - zapthreads(runtime, interp); + PyInterpreterState_Clear(interp); // XXX must activate? + zapthreads(interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -552,7 +542,7 @@ threadstate_getframe(PyThreadState *self) static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = interp->runtime; PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (tstate == NULL) { return NULL; @@ -608,7 +598,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->id = ++interp->tstate_next_unique_id; if (init) { - _PyThreadState_Init(runtime, tstate); + _PyThreadState_Init(tstate); } HEAD_LOCK(runtime); @@ -635,9 +625,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) } void -_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) +_PyThreadState_Init(PyThreadState *tstate) { - _PyGILState_NoteThreadState(&runtime->gilstate, tstate); + _PyGILState_NoteThreadState(&tstate->interp->runtime->gilstate, tstate); } PyObject* @@ -803,8 +793,9 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) +tstate_delete_common(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; if (tstate == NULL) { Py_FatalError("PyThreadState_Delete: NULL tstate"); } @@ -827,10 +818,10 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) } -static void -_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) +void +PyThreadState_Delete(PyThreadState *tstate) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { Py_FatalError("PyThreadState_Delete: tstate is still current"); } @@ -839,14 +830,7 @@ _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) { PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - tstate_delete_common(runtime, tstate); -} - - -void -PyThreadState_Delete(PyThreadState *tstate) -{ - _PyThreadState_Delete(&_PyRuntime, tstate); + tstate_delete_common(tstate); } @@ -858,7 +842,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(runtime, tstate); + tstate_delete_common(tstate); if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { @@ -1134,13 +1118,13 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) +_PyGILState_Init(PyThreadState *tstate) { /* must init with valid states */ assert(tstate != NULL); assert(tstate->interp != NULL); - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { Py_FatalError("Could not allocate TSS entry"); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 92935408a58eb..30c7e987461b2 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2387,17 +2387,18 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(_PyRuntimeState *runtime, PyThreadState *tstate) +make_flags(PyThreadState *tstate) { - int pos = 0; - PyObject *seq; - const PyPreConfig *preconfig = &runtime->preconfig; - const PyConfig *config = &tstate->interp->config; + PyInterpreterState *interp = tstate->interp; + const PyPreConfig *preconfig = &interp->runtime->preconfig; + const PyConfig *config = &interp->config; - seq = PyStructSequence_New(&FlagsType); - if (seq == NULL) + PyObject *seq = PyStructSequence_New(&FlagsType); + if (seq == NULL) { return NULL; + } + int pos = 0; #define SetFlag(flag) \ PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag)) @@ -2607,8 +2608,7 @@ static struct PyModuleDef sysmodule = { } while (0) static PyStatus -_PySys_InitCore(_PyRuntimeState *runtime, PyThreadState *tstate, - PyObject *sysdict) +_PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) { PyObject *version_info; int res; @@ -2703,7 +2703,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyThreadState *tstate, } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(runtime, tstate)); + SET_SYS_FROM_STRING("flags", make_flags(tstate)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2824,7 +2824,7 @@ sys_create_xoptions_dict(const PyConfig *config) int -_PySys_InitMain(_PyRuntimeState *runtime, PyThreadState *tstate) +_PySys_InitMain(PyThreadState *tstate) { PyObject *sysdict = tstate->interp->sysdict; const PyConfig *config = &tstate->interp->config; @@ -2879,7 +2879,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyThreadState *tstate) #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, tstate)); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(tstate)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2944,8 +2944,7 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ PyStatus -_PySys_Create(_PyRuntimeState *runtime, PyThreadState *tstate, - PyObject **sysmod_p) +_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) { PyInterpreterState *interp = tstate->interp; @@ -2976,7 +2975,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyThreadState *tstate, return status; } - status = _PySys_InitCore(runtime, tstate, sysdict); + status = _PySys_InitCore(tstate, sysdict); if (_PyStatus_EXCEPTION(status)) { return status; } From webhook-mailer at python.org Tue Nov 19 20:51:34 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 01:51:34 -0000 Subject: [Python-checkins] bpo-38835: Don't use PyFPE_START_PROTECT and PyFPE_END_PROTECT (GH-17231) Message-ID: https://github.com/python/cpython/commit/be143ec99674ba38c5811f34cdb85ef39c2dc8f8 commit: be143ec99674ba38c5811f34cdb85ef39c2dc8f8 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T02:51:30+01:00 summary: bpo-38835: Don't use PyFPE_START_PROTECT and PyFPE_END_PROTECT (GH-17231) The PyFPE_START_PROTECT() and PyFPE_END_PROTECT() macros are empty: they have been doing nothing for the last year (since commit 735ae8d139a673b30b321dc10acfd3d14f0d633b), so stop using them. files: A Misc/NEWS.d/next/Core and Builtins/2019-11-18-16-37-49.bpo-38835.-U4se1.rst M Modules/_tkinter.c M Modules/clinic/cmathmodule.c.h M Modules/cmathmodule.c M Modules/mathmodule.c M Objects/complexobject.c M Objects/floatobject.c M Python/bltinmodule.c M Python/pystrtod.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-18-16-37-49.bpo-38835.-U4se1.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-18-16-37-49.bpo-38835.-U4se1.rst new file mode 100644 index 0000000000000..edc70b137ba9f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-18-16-37-49.bpo-38835.-U4se1.rst @@ -0,0 +1,2 @@ +The ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` macros are empty: +they have been doing nothing for the last year, so stop using them. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 40d2ed7f88b11..4f7d1b78ebe81 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -2166,11 +2166,9 @@ _tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; - PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) ENTER_TCL retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); ENTER_OVERLAP - PyFPE_END_PROTECT(retval) if (retval == TCL_ERROR) res = Tkinter_Error(self); else diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index 81a8437c3a7d1..4b6653aa21942 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -26,9 +26,8 @@ cmath_acos(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_acos_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -69,9 +68,8 @@ cmath_acosh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_acosh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -112,9 +110,8 @@ cmath_asin(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_asin_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -155,9 +152,8 @@ cmath_asinh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_asinh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -198,9 +194,8 @@ cmath_atan(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_atan_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -241,9 +236,8 @@ cmath_atanh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_atanh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -284,9 +278,8 @@ cmath_cos(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_cos_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -327,9 +320,8 @@ cmath_cosh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_cosh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -370,9 +362,8 @@ cmath_exp(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_exp_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -413,9 +404,8 @@ cmath_log10(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_log10_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -456,9 +446,8 @@ cmath_sin(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_sin_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -499,9 +488,8 @@ cmath_sinh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_sinh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -542,9 +530,8 @@ cmath_sqrt(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_sqrt_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -585,9 +572,8 @@ cmath_tan(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_tan_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -628,9 +614,8 @@ cmath_tanh(PyObject *module, PyObject *arg) goto exit; } /* modifications for z */ - errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + errno = 0; _return_value = cmath_tanh_impl(module, z); - PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -968,4 +953,4 @@ cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=3edc4484b10ae752 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=353347db2e808e0d input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 02c09bbea48ac..8b21decfa53fc 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -17,7 +17,7 @@ module cmath /*[python input] class Py_complex_protected_converter(Py_complex_converter): def modify(self): - return 'errno = 0; PyFPE_START_PROTECT("complex function", goto exit);' + return 'errno = 0;' class Py_complex_protected_return_converter(CReturnConverter): @@ -26,7 +26,6 @@ class Py_complex_protected_return_converter(CReturnConverter): def render(self, function, data): self.declare(data) data.return_conversion.append(""" -PyFPE_END_PROTECT(_return_value); if (errno == EDOM) { PyErr_SetString(PyExc_ValueError, "math domain error"); goto exit; @@ -40,7 +39,7 @@ else { } """.strip()) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=345daa075b1028e7]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=8b27adb674c08321]*/ #if (FLT_RADIX != 2 && FLT_RADIX != 16) #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" @@ -960,7 +959,6 @@ cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) Py_complex y; errno = 0; - PyFPE_START_PROTECT("complex function", return 0) x = c_log(x); if (y_obj != NULL) { y = PyComplex_AsCComplex(y_obj); @@ -970,7 +968,6 @@ cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) y = c_log(y); x = _Py_c_quot(x, y); } - PyFPE_END_PROTECT(x) if (errno != 0) return math_error(); return PyComplex_FromCComplex(x); @@ -1008,9 +1005,7 @@ cmath_phase_impl(PyObject *module, Py_complex z) double phi; errno = 0; - PyFPE_START_PROTECT("arg function", return 0) phi = c_atan2(z); - PyFPE_END_PROTECT(phi) if (errno != 0) return math_error(); else @@ -1035,10 +1030,8 @@ cmath_polar_impl(PyObject *module, Py_complex z) double r, phi; errno = 0; - PyFPE_START_PROTECT("polar function", return 0) phi = c_atan2(z); /* should not cause any exception */ r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ - PyFPE_END_PROTECT(r) if (errno != 0) return math_error(); else @@ -1074,7 +1067,6 @@ cmath_rect_impl(PyObject *module, double r, double phi) { Py_complex z; errno = 0; - PyFPE_START_PROTECT("rect function", return 0) /* deal with special values */ if (!Py_IS_FINITE(r) || !Py_IS_FINITE(phi)) { @@ -1116,7 +1108,6 @@ cmath_rect_impl(PyObject *module, double r, double phi) errno = 0; } - PyFPE_END_PROTECT(z) if (errno != 0) return math_error(); else diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index eaaeedbef3823..e60e19bc49095 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -936,9 +936,7 @@ math_1_to_whatever(PyObject *arg, double (*func) (double), if (x == -1.0 && PyErr_Occurred()) return NULL; errno = 0; - PyFPE_START_PROTECT("in math_1", return 0); r = (*func)(x); - PyFPE_END_PROTECT(r); if (Py_IS_NAN(r) && !Py_IS_NAN(x)) { PyErr_SetString(PyExc_ValueError, "math domain error"); /* invalid arg */ @@ -972,9 +970,7 @@ math_1a(PyObject *arg, double (*func) (double)) if (x == -1.0 && PyErr_Occurred()) return NULL; errno = 0; - PyFPE_START_PROTECT("in math_1a", return 0); r = (*func)(x); - PyFPE_END_PROTECT(r); if (errno && is_error(r)) return NULL; return PyFloat_FromDouble(r); @@ -1025,9 +1021,7 @@ math_2(PyObject *const *args, Py_ssize_t nargs, if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) return NULL; errno = 0; - PyFPE_START_PROTECT("in math_2", return 0); r = (*func)(x, y); - PyFPE_END_PROTECT(r); if (Py_IS_NAN(r)) { if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) errno = EDOM; @@ -1340,8 +1334,6 @@ math_fsum(PyObject *module, PyObject *seq) if (iter == NULL) return NULL; - PyFPE_START_PROTECT("fsum", Py_DECREF(iter); return NULL) - for(;;) { /* for x in iterable */ assert(0 <= n && n <= m); assert((m == NUM_PARTIALS && p == ps) || @@ -1436,7 +1428,6 @@ math_fsum(PyObject *module, PyObject *seq) sum = PyFloat_FromDouble(hi); _fsum_error: - PyFPE_END_PROTECT(hi) Py_DECREF(iter); if (p != ps) PyMem_Free(p); @@ -2111,9 +2102,7 @@ math_frexp_impl(PyObject *module, double x) i = 0; } else { - PyFPE_START_PROTECT("in math_frexp", return 0); x = frexp(x, &i); - PyFPE_END_PROTECT(x); } return Py_BuildValue("(di)", x, i); } @@ -2168,9 +2157,7 @@ math_ldexp_impl(PyObject *module, double x, PyObject *i) errno = 0; } else { errno = 0; - PyFPE_START_PROTECT("in math_ldexp", return 0); r = ldexp(x, (int)exp); - PyFPE_END_PROTECT(r); if (Py_IS_INFINITY(r)) errno = ERANGE; } @@ -2207,9 +2194,7 @@ math_modf_impl(PyObject *module, double x) } errno = 0; - PyFPE_START_PROTECT("in math_modf", return 0); x = modf(x, &y); - PyFPE_END_PROTECT(x); return Py_BuildValue("(dd)", x, y); } @@ -2356,9 +2341,7 @@ math_fmod_impl(PyObject *module, double x, double y) if (Py_IS_INFINITY(y) && Py_IS_FINITE(x)) return PyFloat_FromDouble(x); errno = 0; - PyFPE_START_PROTECT("in math_fmod", return 0); r = fmod(x, y); - PyFPE_END_PROTECT(r); if (Py_IS_NAN(r)) { if (!Py_IS_NAN(x) && !Py_IS_NAN(y)) errno = EDOM; @@ -2646,9 +2629,7 @@ math_pow_impl(PyObject *module, double x, double y) else { /* let libm handle finite**finite */ errno = 0; - PyFPE_START_PROTECT("in math_pow", return 0); r = pow(x, y); - PyFPE_END_PROTECT(r); /* a NaN result should arise only from (-ve)**(finite non-integer); in this case we want to raise ValueError. */ if (!Py_IS_FINITE(r)) { diff --git a/Objects/complexobject.c b/Objects/complexobject.c index a49da4018411e..367752db78f5f 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -466,9 +466,7 @@ complex_add(PyObject *v, PyObject *w) Py_complex a, b; TO_COMPLEX(v, a); TO_COMPLEX(w, b); - PyFPE_START_PROTECT("complex_add", return 0) result = _Py_c_sum(a, b); - PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -479,9 +477,7 @@ complex_sub(PyObject *v, PyObject *w) Py_complex a, b; TO_COMPLEX(v, a); TO_COMPLEX(w, b); - PyFPE_START_PROTECT("complex_sub", return 0) result = _Py_c_diff(a, b); - PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -492,9 +488,7 @@ complex_mul(PyObject *v, PyObject *w) Py_complex a, b; TO_COMPLEX(v, a); TO_COMPLEX(w, b); - PyFPE_START_PROTECT("complex_mul", return 0) result = _Py_c_prod(a, b); - PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -505,10 +499,8 @@ complex_div(PyObject *v, PyObject *w) Py_complex a, b; TO_COMPLEX(v, a); TO_COMPLEX(w, b); - PyFPE_START_PROTECT("complex_div", return 0) errno = 0; quot = _Py_c_quot(a, b); - PyFPE_END_PROTECT(quot) if (errno == EDOM) { PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); return NULL; @@ -547,7 +539,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) PyErr_SetString(PyExc_ValueError, "complex modulo"); return NULL; } - PyFPE_START_PROTECT("complex_pow", return 0) errno = 0; exponent = b; int_exponent = (long)exponent.real; @@ -556,7 +547,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) else p = _Py_c_pow(a, exponent); - PyFPE_END_PROTECT(p) Py_ADJUST_ERANGE2(p.real, p.imag); if (errno == EDOM) { PyErr_SetString(PyExc_ZeroDivisionError, @@ -604,9 +594,7 @@ complex_abs(PyComplexObject *v) { double result; - PyFPE_START_PROTECT("complex_abs", return 0) result = _Py_c_abs(v->cval); - PyFPE_END_PROTECT(result) if (errno == ERANGE) { PyErr_SetString(PyExc_OverflowError, diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 3f9bbde2abe03..20a5155e07346 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -506,7 +506,6 @@ float_richcompare(PyObject *v, PyObject *w, int op) goto Unimplemented; Compare: - PyFPE_START_PROTECT("richcompare", return NULL) switch (op) { case Py_EQ: r = i == j; @@ -527,7 +526,6 @@ float_richcompare(PyObject *v, PyObject *w, int op) r = i > j; break; } - PyFPE_END_PROTECT(r) return PyBool_FromLong(r); Unimplemented: @@ -546,9 +544,7 @@ float_add(PyObject *v, PyObject *w) double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); - PyFPE_START_PROTECT("add", return 0) a = a + b; - PyFPE_END_PROTECT(a) return PyFloat_FromDouble(a); } @@ -558,9 +554,7 @@ float_sub(PyObject *v, PyObject *w) double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); - PyFPE_START_PROTECT("subtract", return 0) a = a - b; - PyFPE_END_PROTECT(a) return PyFloat_FromDouble(a); } @@ -570,9 +564,7 @@ float_mul(PyObject *v, PyObject *w) double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); - PyFPE_START_PROTECT("multiply", return 0) a = a * b; - PyFPE_END_PROTECT(a) return PyFloat_FromDouble(a); } @@ -587,9 +579,7 @@ float_div(PyObject *v, PyObject *w) "float division by zero"); return NULL; } - PyFPE_START_PROTECT("divide", return 0) a = a / b; - PyFPE_END_PROTECT(a) return PyFloat_FromDouble(a); } @@ -605,7 +595,6 @@ float_rem(PyObject *v, PyObject *w) "float modulo"); return NULL; } - PyFPE_START_PROTECT("modulo", return 0) mod = fmod(vx, wx); if (mod) { /* ensure the remainder has the same sign as the denominator */ @@ -619,7 +608,6 @@ float_rem(PyObject *v, PyObject *w) it has the same sign as the denominator. */ mod = copysign(0.0, wx); } - PyFPE_END_PROTECT(mod) return PyFloat_FromDouble(mod); } @@ -634,7 +622,6 @@ float_divmod(PyObject *v, PyObject *w) PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); return NULL; } - PyFPE_START_PROTECT("divmod", return 0) mod = fmod(vx, wx); /* fmod is typically exact, so vx-mod is *mathematically* an exact multiple of wx. But this is fp arithmetic, and fp @@ -666,7 +653,6 @@ float_divmod(PyObject *v, PyObject *w) /* div is zero - get the same sign as the true quotient */ floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */ } - PyFPE_END_PROTECT(floordiv) return Py_BuildValue("(dd)", floordiv, mod); } @@ -793,9 +779,7 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) * the platform pow to step in and do the rest. */ errno = 0; - PyFPE_START_PROTECT("pow", return NULL) ix = pow(iv, iw); - PyFPE_END_PROTECT(ix) Py_ADJUST_ERANGE1(ix); if (negate_result) ix = -ix; @@ -849,9 +833,7 @@ float_is_integer_impl(PyObject *self) if (!Py_IS_FINITE(x)) Py_RETURN_FALSE; errno = 0; - PyFPE_START_PROTECT("is_integer", return NULL) o = (floor(x) == x) ? Py_True : Py_False; - PyFPE_END_PROTECT(x) if (errno != 0) { PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : PyExc_ValueError); @@ -1567,9 +1549,7 @@ float_as_integer_ratio_impl(PyObject *self) return NULL; } - PyFPE_START_PROTECT("as_integer_ratio", goto error); float_part = frexp(self_double, &exponent); /* self_double == float_part * 2**exponent exactly */ - PyFPE_END_PROTECT(float_part); for (i=0; i<300 && float_part != floor(float_part) ; i++) { float_part *= 2.0; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 4470310a84e73..34267685be2f1 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2385,9 +2385,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) return PyFloat_FromDouble(f_result); } if (PyFloat_CheckExact(item)) { - PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += PyFloat_AS_DOUBLE(item); - PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; } @@ -2396,9 +2394,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) int overflow; value = PyLong_AsLongAndOverflow(item, &overflow); if (!overflow) { - PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0) f_result += (double)value; - PyFPE_END_PROTECT(f_result) Py_DECREF(item); continue; } diff --git a/Python/pystrtod.c b/Python/pystrtod.c index 4aa99d546caf9..94dc4818c2f47 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -342,9 +342,7 @@ PyOS_string_to_double(const char *s, char *fail_pos; errno = 0; - PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0) x = _PyOS_ascii_strtod(s, &fail_pos); - PyFPE_END_PROTECT(x) if (errno == ENOMEM) { PyErr_NoMemory(); From webhook-mailer at python.org Tue Nov 19 23:39:21 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 20 Nov 2019 04:39:21 -0000 Subject: [Python-checkins] closes bpo-38712: Add signal.pidfd_send_signal. (GH-17070) Message-ID: https://github.com/python/cpython/commit/7483451577916e693af6d20cf520b2cc7e2174d2 commit: 7483451577916e693af6d20cf520b2cc7e2174d2 branch: master author: Benjamin Peterson committer: GitHub date: 2019-11-19T20:39:14-08:00 summary: closes bpo-38712: Add signal.pidfd_send_signal. (GH-17070) This exposes a Linux-specific syscall for sending a signal to a process identified by a file descriptor rather than a pid. For simplicity, we don't support the siginfo_t parameter to the syscall. This parameter allows implementing a pidfd version of rt_sigqueueinfo(2), which Python also doesn't support. files: A Misc/NEWS.d/next/Library/2019-11-05-21-10-12.bpo-38712.ezJ0TP.rst M Doc/library/signal.rst M Doc/whatsnew/3.9.rst M Lib/test/test_signal.py M Modules/clinic/signalmodule.c.h M Modules/signalmodule.c diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 8fecc2b7eed0e..a79fc501352d4 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -247,6 +247,19 @@ The :mod:`signal` module defines the following functions: .. versionadded:: 3.8 +.. function:: pidfd_send_signal(pidfd, sig, siginfo=None, flags=0) + + Send signal *sig* to the process referred to by file descriptor *pidfd*. + Python does not currently support the *siginfo* parameter; it must be + ``None``. The *flags* argument is provided for future extensions; no flag + values are currently defined. + + See the :manpage:`pidfd_send_signal(2)` man page for more information. + + .. availability:: Linux 5.1+ + .. versionadded:: 3.9 + + .. function:: pthread_kill(thread_id, signalnum) Send the signal *signalnum* to the thread *thread_id*, another thread in the diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ddb295f845c75..ce1d3e0e96a58 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -197,6 +197,13 @@ now raises :exc:`ImportError` instead of :exc:`ValueError` for invalid relative import attempts. (Contributed by Ngalim Siregar in :issue:`37444`.) +signal +------ + +Exposed the Linux-specific :func:`signal.pidfd_send_signal` for sending to +signals to a process using a file descriptor instead of a pid. (:issue:`38712`) + + Optimizations ============= diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index d41e94b07f430..119e9e079ac03 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1273,6 +1273,25 @@ def handler(a, b): self.assertTrue(is_ok) +class PidfdSignalTest(unittest.TestCase): + + @unittest.skipUnless( + hasattr(signal, "pidfd_send_signal"), + "pidfd support not built in", + ) + def test_pidfd_send_signal(self): + with self.assertRaises(OSError) as cm: + signal.pidfd_send_signal(0, signal.SIGINT) + if cm.exception.errno == errno.ENOSYS: + self.skipTest("kernel does not support pidfds") + self.assertEqual(cm.exception.errno, errno.EBADF) + my_pidfd = os.open(f'/proc/{os.getpid()}', os.O_DIRECTORY) + self.addCleanup(os.close, my_pidfd) + with self.assertRaisesRegexp(TypeError, "^siginfo must be None$"): + signal.pidfd_send_signal(my_pidfd, signal.SIGINT, object(), 0) + with self.assertRaises(KeyboardInterrupt): + signal.pidfd_send_signal(my_pidfd, signal.SIGINT) + def tearDownModule(): support.reap_children() diff --git a/Misc/NEWS.d/next/Library/2019-11-05-21-10-12.bpo-38712.ezJ0TP.rst b/Misc/NEWS.d/next/Library/2019-11-05-21-10-12.bpo-38712.ezJ0TP.rst new file mode 100644 index 0000000000000..81d01aa7111d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-05-21-10-12.bpo-38712.ezJ0TP.rst @@ -0,0 +1,3 @@ +Add the Linux-specific :func:`signal.pidfd_send_signal` function, which +allows sending a signal to a process identified by a file descriptor rather +than a pid. diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 3cb1db14878c5..7f60e28a3a28a 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -611,6 +611,76 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #endif /* defined(HAVE_PTHREAD_KILL) */ +#if (defined(__linux__) && defined(__NR_pidfd_send_signal)) + +PyDoc_STRVAR(signal_pidfd_send_signal__doc__, +"pidfd_send_signal($module, pidfd, signalnum, siginfo=None, flags=0, /)\n" +"--\n" +"\n" +"Send a signal to a process referred to by a pid file descriptor."); + +#define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF \ + {"pidfd_send_signal", (PyCFunction)(void(*)(void))signal_pidfd_send_signal, METH_FASTCALL, signal_pidfd_send_signal__doc__}, + +static PyObject * +signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, + PyObject *siginfo, int flags); + +static PyObject * +signal_pidfd_send_signal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int pidfd; + int signalnum; + PyObject *siginfo = Py_None; + int flags = 0; + + if (!_PyArg_CheckPositional("pidfd_send_signal", nargs, 2, 4)) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + pidfd = _PyLong_AsInt(args[0]); + if (pidfd == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + signalnum = _PyLong_AsInt(args[1]); + if (signalnum == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + siginfo = args[2]; + if (nargs < 4) { + goto skip_optional; + } + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = _PyLong_AsInt(args[3]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = signal_pidfd_send_signal_impl(module, pidfd, signalnum, siginfo, flags); + +exit: + return return_value; +} + +#endif /* (defined(__linux__) && defined(__NR_pidfd_send_signal)) */ + #ifndef SIGNAL_ALARM_METHODDEF #define SIGNAL_ALARM_METHODDEF #endif /* !defined(SIGNAL_ALARM_METHODDEF) */ @@ -658,4 +728,8 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef SIGNAL_PTHREAD_KILL_METHODDEF #define SIGNAL_PTHREAD_KILL_METHODDEF #endif /* !defined(SIGNAL_PTHREAD_KILL_METHODDEF) */ -/*[clinic end generated code: output=3320b8f73c20ba60 input=a9049054013a1b77]*/ + +#ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF + #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF +#endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */ +/*[clinic end generated code: output=b41b4b6bd9ad4da2 input=a9049054013a1b77]*/ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 1d99f877e1620..693b90b6c631e 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -25,6 +25,9 @@ #ifdef HAVE_SIGNAL_H #include #endif +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif #ifdef HAVE_SYS_STAT_H #include #endif @@ -1250,6 +1253,38 @@ signal_pthread_kill_impl(PyObject *module, unsigned long thread_id, #endif /* #if defined(HAVE_PTHREAD_KILL) */ +#if defined(__linux__) && defined(__NR_pidfd_send_signal) +/*[clinic input] +signal.pidfd_send_signal + + pidfd: int + signalnum: int + siginfo: object = None + flags: int = 0 + / + +Send a signal to a process referred to by a pid file descriptor. +[clinic start generated code]*/ + +static PyObject * +signal_pidfd_send_signal_impl(PyObject *module, int pidfd, int signalnum, + PyObject *siginfo, int flags) +/*[clinic end generated code: output=2d59f04a75d9cbdf input=2a6543a1f4ac2000]*/ + +{ + if (siginfo != Py_None) { + PyErr_SetString(PyExc_TypeError, "siginfo must be None"); + return NULL; + } + if (syscall(__NR_pidfd_send_signal, pidfd, signalnum, NULL, flags) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + Py_RETURN_NONE; +} +#endif + + /* List of functions defined in the module -- some of the methoddefs are defined to nothing if the corresponding C function is not available. */ @@ -1265,6 +1300,7 @@ static PyMethodDef signal_methods[] = { {"set_wakeup_fd", (PyCFunction)(void(*)(void))signal_set_wakeup_fd, METH_VARARGS | METH_KEYWORDS, set_wakeup_fd_doc}, SIGNAL_SIGINTERRUPT_METHODDEF SIGNAL_PAUSE_METHODDEF + SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF SIGNAL_PTHREAD_KILL_METHODDEF SIGNAL_PTHREAD_SIGMASK_METHODDEF SIGNAL_SIGPENDING_METHODDEF From webhook-mailer at python.org Wed Nov 20 01:18:53 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Wed, 20 Nov 2019 06:18:53 -0000 Subject: [Python-checkins] bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) Message-ID: https://github.com/python/cpython/commit/b8462477bfd01ff21461065d5063e6b0238ca809 commit: b8462477bfd01ff21461065d5063e6b0238ca809 branch: master author: Terry Jan Reedy committer: GitHub date: 2019-11-20T01:18:39-05:00 summary: bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) These Format menu functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. files: A Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/editor.py M Lib/idlelib/format.py M Lib/idlelib/idle_test/test_format.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index b02a9880505e8..c6aa00d0d54b3 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,10 @@ Released on 2020-10-05? ====================================== +bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These +functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled +in 3.7.5 and 3.8.0. + bpo-4360: Add an option to toggle IDLE's cursor blink for shell, editor, and output windows. See Settings, General, Window Preferences, Cursor Blink. Patch by Zachary Spytz. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index dff104ff0f18f..92dcf57c4ff26 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -186,8 +186,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", fregion.uncomment_region_event) text.bind("<>", fregion.tabify_region_event) text.bind("<>", fregion.untabify_region_event) - text.bind("<>", self.Indents.toggle_tabs_event) - text.bind("<>", self.Indents.change_indentwidth_event) + indents = self.Indents(self) + text.bind("<>", indents.toggle_tabs_event) + text.bind("<>", indents.change_indentwidth_event) text.bind("", self.move_at_edge_if_selection(0)) text.bind("", self.move_at_edge_if_selection(1)) text.bind("<>", self.del_word_left) diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index bced4c1770eb0..2b0980565734a 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -353,8 +353,7 @@ def _asktabwidth(self): maxvalue=16) -# With mixed indents not allowed, these are semi-useless and not unittested. -class Indents: # pragma: no cover +class Indents: "Change future indents." def __init__(self, editwin): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index c7b123e9d513a..20b5970f4982d 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -417,7 +417,7 @@ def tearDown(self): self.text.delete('1.0', 'end') code_sample = """\ - +# WS line needed for test. class C1(): # Class comment. def __init__(self, a, b): @@ -574,7 +574,42 @@ def test_ask_tabwidth(self, askinteger): self.assertEqual(ask(), 10) -class rstripTest(unittest.TestCase): +class IndentsTest(unittest.TestCase): + + @mock.patch.object(ft, "askyesno") + def test_toggle_tabs(self, askyesno): + editor = DummyEditwin(None, None) # usetabs == False. + indents = ft.Indents(editor) + askyesno.return_value = True + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, True) + self.assertEqual(editor.indentwidth, 8) + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, False) + self.assertEqual(editor.indentwidth, 8) + + @mock.patch.object(ft, "askinteger") + def test_change_indentwidth(self, askinteger): + editor = DummyEditwin(None, None) # indentwidth == 4. + indents = ft.Indents(editor) + + askinteger.return_value = None + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 4) + + askinteger.return_value = 3 + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + askinteger.return_value = 5 + editor.usetabs = True + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + +class RstripTest(unittest.TestCase): def test_rstrip_line(self): editor = MockEditor() diff --git a/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst new file mode 100644 index 0000000000000..4262dbea6d867 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst @@ -0,0 +1,3 @@ +Fix IDLE Format menu tab toggle and file indent width. These functions +(default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 +and 3.8.0. From webhook-mailer at python.org Wed Nov 20 01:37:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 06:37:14 -0000 Subject: [Python-checkins] bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) Message-ID: https://github.com/python/cpython/commit/755caaa753577b907bb7e94560f8adf5eb694d6b commit: 755caaa753577b907bb7e94560f8adf5eb694d6b branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T22:37:09-08:00 summary: bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) These Format menu functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. (cherry picked from commit b8462477bfd01ff21461065d5063e6b0238ca809) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/editor.py M Lib/idlelib/format.py M Lib/idlelib/idle_test/test_format.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 2fd2ea19b5a0f..53348ee0af0e9 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,10 @@ Released on 2019-12-16? ====================================== +bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These +functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled +in 3.7.5 and 3.8.0. + bpo-4360: Add an option to toggle IDLE's cursor blink for shell, editor, and output windows. See Settings, General, Window Preferences, Cursor Blink. Patch by Zachary Spytz. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index dff104ff0f18f..92dcf57c4ff26 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -186,8 +186,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", fregion.uncomment_region_event) text.bind("<>", fregion.tabify_region_event) text.bind("<>", fregion.untabify_region_event) - text.bind("<>", self.Indents.toggle_tabs_event) - text.bind("<>", self.Indents.change_indentwidth_event) + indents = self.Indents(self) + text.bind("<>", indents.toggle_tabs_event) + text.bind("<>", indents.change_indentwidth_event) text.bind("", self.move_at_edge_if_selection(0)) text.bind("", self.move_at_edge_if_selection(1)) text.bind("<>", self.del_word_left) diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index bced4c1770eb0..2b0980565734a 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -353,8 +353,7 @@ def _asktabwidth(self): maxvalue=16) -# With mixed indents not allowed, these are semi-useless and not unittested. -class Indents: # pragma: no cover +class Indents: "Change future indents." def __init__(self, editwin): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index c7b123e9d513a..20b5970f4982d 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -417,7 +417,7 @@ def tearDown(self): self.text.delete('1.0', 'end') code_sample = """\ - +# WS line needed for test. class C1(): # Class comment. def __init__(self, a, b): @@ -574,7 +574,42 @@ def test_ask_tabwidth(self, askinteger): self.assertEqual(ask(), 10) -class rstripTest(unittest.TestCase): +class IndentsTest(unittest.TestCase): + + @mock.patch.object(ft, "askyesno") + def test_toggle_tabs(self, askyesno): + editor = DummyEditwin(None, None) # usetabs == False. + indents = ft.Indents(editor) + askyesno.return_value = True + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, True) + self.assertEqual(editor.indentwidth, 8) + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, False) + self.assertEqual(editor.indentwidth, 8) + + @mock.patch.object(ft, "askinteger") + def test_change_indentwidth(self, askinteger): + editor = DummyEditwin(None, None) # indentwidth == 4. + indents = ft.Indents(editor) + + askinteger.return_value = None + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 4) + + askinteger.return_value = 3 + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + askinteger.return_value = 5 + editor.usetabs = True + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + +class RstripTest(unittest.TestCase): def test_rstrip_line(self): editor = MockEditor() diff --git a/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst new file mode 100644 index 0000000000000..4262dbea6d867 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst @@ -0,0 +1,3 @@ +Fix IDLE Format menu tab toggle and file indent width. These functions +(default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 +and 3.8.0. From webhook-mailer at python.org Wed Nov 20 01:37:51 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 06:37:51 -0000 Subject: [Python-checkins] bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) Message-ID: https://github.com/python/cpython/commit/132243957ce834cf5ffced4bf8e39d00f6e34e5f commit: 132243957ce834cf5ffced4bf8e39d00f6e34e5f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-19T22:37:47-08:00 summary: bpo-38636: Fix IDLE tab toggle and file indent width (GH-17008) These Format menu functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. (cherry picked from commit b8462477bfd01ff21461065d5063e6b0238ca809) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/editor.py M Lib/idlelib/format.py M Lib/idlelib/idle_test/test_format.py diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index fba936982616c..153c7630cf8be 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,10 @@ Released on 2019-12-16? ====================================== +bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These +functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled +in 3.7.5 and 3.8.0. + bpo-4360: Add an option to toggle IDLE's cursor blink for shell, editor, and output windows. See Settings, General, Window Preferences, Cursor Blink. Patch by Zachary Spytz. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index dff104ff0f18f..92dcf57c4ff26 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -186,8 +186,9 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", fregion.uncomment_region_event) text.bind("<>", fregion.tabify_region_event) text.bind("<>", fregion.untabify_region_event) - text.bind("<>", self.Indents.toggle_tabs_event) - text.bind("<>", self.Indents.change_indentwidth_event) + indents = self.Indents(self) + text.bind("<>", indents.toggle_tabs_event) + text.bind("<>", indents.change_indentwidth_event) text.bind("", self.move_at_edge_if_selection(0)) text.bind("", self.move_at_edge_if_selection(1)) text.bind("<>", self.del_word_left) diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index bced4c1770eb0..2b0980565734a 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -353,8 +353,7 @@ def _asktabwidth(self): maxvalue=16) -# With mixed indents not allowed, these are semi-useless and not unittested. -class Indents: # pragma: no cover +class Indents: "Change future indents." def __init__(self, editwin): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index c7b123e9d513a..20b5970f4982d 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -417,7 +417,7 @@ def tearDown(self): self.text.delete('1.0', 'end') code_sample = """\ - +# WS line needed for test. class C1(): # Class comment. def __init__(self, a, b): @@ -574,7 +574,42 @@ def test_ask_tabwidth(self, askinteger): self.assertEqual(ask(), 10) -class rstripTest(unittest.TestCase): +class IndentsTest(unittest.TestCase): + + @mock.patch.object(ft, "askyesno") + def test_toggle_tabs(self, askyesno): + editor = DummyEditwin(None, None) # usetabs == False. + indents = ft.Indents(editor) + askyesno.return_value = True + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, True) + self.assertEqual(editor.indentwidth, 8) + + indents.toggle_tabs_event(None) + self.assertEqual(editor.usetabs, False) + self.assertEqual(editor.indentwidth, 8) + + @mock.patch.object(ft, "askinteger") + def test_change_indentwidth(self, askinteger): + editor = DummyEditwin(None, None) # indentwidth == 4. + indents = ft.Indents(editor) + + askinteger.return_value = None + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 4) + + askinteger.return_value = 3 + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + askinteger.return_value = 5 + editor.usetabs = True + indents.change_indentwidth_event(None) + self.assertEqual(editor.indentwidth, 3) + + +class RstripTest(unittest.TestCase): def test_rstrip_line(self): editor = MockEditor() diff --git a/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst new file mode 100644 index 0000000000000..4262dbea6d867 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-10-30-22-11-16.bpo-38636.hUhDeB.rst @@ -0,0 +1,3 @@ +Fix IDLE Format menu tab toggle and file indent width. These functions +(default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 +and 3.8.0. From webhook-mailer at python.org Wed Nov 20 04:38:40 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 09:38:40 -0000 Subject: [Python-checkins] bpo-38858: Factorize Py_EndInterpreter() code (GH-17273) Message-ID: https://github.com/python/cpython/commit/7eee5beaf87be898a679278c480e8dd0df76d351 commit: 7eee5beaf87be898a679278c480e8dd0df76d351 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T10:38:34+01:00 summary: bpo-38858: Factorize Py_EndInterpreter() code (GH-17273) * Factorize code in common between Py_FinalizeEx() and Py_EndInterpreter(). * Py_EndInterpreter() now also calls _PyWarnings_Fini(). * Call _PyExc_Fini() and _PyGC_Fini() later in the finalization. files: M Include/internal/pycore_pylifecycle.h M Modules/gcmodule.c M Python/pylifecycle.c M Python/pystate.c diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index f269ffe786893..b2f2ad841c8e0 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -76,7 +76,7 @@ extern void PyOS_FiniInterrupts(void); extern void _PyExc_Fini(void); extern void _PyImport_Fini(void); extern void _PyImport_Fini2(void); -extern void _PyGC_Fini(struct pyruntimestate *runtime); +extern void _PyGC_Fini(PyThreadState *tstate); extern void _PyType_Fini(void); extern void _Py_HashRandomization_Fini(void); extern void _PyUnicode_Fini(void); @@ -87,7 +87,7 @@ extern void _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); extern void _PyGILState_Init(PyThreadState *tstate); -extern void _PyGILState_Fini(struct pyruntimestate *runtime); +extern void _PyGILState_Fini(PyThreadState *tstate); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 05ca026189b67..518b0547d2745 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -2038,9 +2038,9 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime) } void -_PyGC_Fini(_PyRuntimeState *runtime) +_PyGC_Fini(PyThreadState *tstate) { - struct _gc_runtime_state *state = &runtime->gc; + struct _gc_runtime_state *state = &tstate->interp->runtime->gc; Py_CLEAR(state->garbage); Py_CLEAR(state->callbacks); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index edff7f8f5e2a2..2975b3ebd6651 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1161,6 +1161,78 @@ flush_std_files(void) */ + +static void +finalize_interp_types(PyThreadState *tstate, int is_main_interp) +{ + if (is_main_interp) { + /* Sundry finalizers */ + _PyMethod_Fini(); + _PyFrame_Fini(); + _PyCFunction_Fini(); + _PyTuple_Fini(); + _PyList_Fini(); + _PySet_Fini(); + _PyBytes_Fini(); + _PyLong_Fini(); + _PyFloat_Fini(); + _PyDict_Fini(); + _PySlice_Fini(); + } + + _PyWarnings_Fini(tstate->interp); + + if (is_main_interp) { + _Py_HashRandomization_Fini(); + _PyArg_Fini(); + _PyAsyncGen_Fini(); + _PyContext_Fini(); + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(); + _Py_ClearFileSystemEncoding(); + } +} + + +static void +finalize_interp_clear(PyThreadState *tstate, int is_main_interp) +{ + /* Clear interpreter state and all thread states */ + PyInterpreterState_Clear(tstate->interp); + + 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 + */ + + PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + + _PyExc_Fini(); + _PyGC_Fini(tstate); + } +} + + +static void +finalize_interp_delete(PyThreadState *tstate, int is_main_interp) +{ + if (is_main_interp) { + /* Cleanup auto-thread-state */ + _PyGILState_Fini(tstate); + } + + /* Delete current thread. After this, many C API calls become crashy. */ + PyThreadState_Swap(NULL); + + PyInterpreterState_Delete(tstate->interp); +} + + int Py_FinalizeEx(void) { @@ -1314,56 +1386,9 @@ Py_FinalizeEx(void) } #endif /* Py_TRACE_REFS */ - /* Clear interpreter state and all thread states. */ - PyInterpreterState_Clear(interp); + finalize_interp_clear(tstate, 1); - /* Now we decref the exception classes. After this point nothing - can raise an exception. That's okay, because each Fini() method - below has been checked to make sure no exceptions are ever - raised. - */ - - _PyExc_Fini(); - - /* Sundry finalizers */ - _PyMethod_Fini(); - _PyFrame_Fini(); - _PyCFunction_Fini(); - _PyTuple_Fini(); - _PyList_Fini(); - _PySet_Fini(); - _PyBytes_Fini(); - _PyLong_Fini(); - _PyFloat_Fini(); - _PyDict_Fini(); - _PySlice_Fini(); - _PyGC_Fini(runtime); - _PyWarnings_Fini(interp); - _Py_HashRandomization_Fini(); - _PyArg_Fini(); - _PyAsyncGen_Fini(); - _PyContext_Fini(); - - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(); - - _Py_ClearFileSystemEncoding(); - - /* XXX Still allocated: - - various static ad-hoc pointers to interned strings - - int and float free list blocks - - whatever various modules and libraries allocate - */ - - PyGrammar_RemoveAccelerators(&_PyParser_Grammar); - - /* Cleanup auto-thread-state */ - _PyGILState_Fini(runtime); - - /* Delete current thread. After this, many C API calls become crashy. */ - PyThreadState_Swap(NULL); - - PyInterpreterState_Delete(interp); + finalize_interp_delete(tstate, 1); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. @@ -1607,9 +1632,8 @@ Py_EndInterpreter(PyThreadState *tstate) } _PyImport_Cleanup(tstate); - PyInterpreterState_Clear(interp); - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); + finalize_interp_clear(tstate, 0); + finalize_interp_delete(tstate, 0); } /* Add the __main__ module */ diff --git a/Python/pystate.c b/Python/pystate.c index 99f93bb77c7b8..8fff161dac0f5 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1143,9 +1143,9 @@ _PyGILState_GetInterpreterStateUnsafe(void) } void -_PyGILState_Fini(_PyRuntimeState *runtime) +_PyGILState_Fini(PyThreadState *tstate) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; PyThread_tss_delete(&gilstate->autoTSSkey); gilstate->autoInterpreterState = NULL; } From webhook-mailer at python.org Wed Nov 20 05:00:36 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 10:00:36 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) Message-ID: https://github.com/python/cpython/commit/d51a363a4379385fdfe9c09a56324631465ede29 commit: d51a363a4379385fdfe9c09a56324631465ede29 branch: master author: Brandt Bucher committer: Victor Stinner date: 2019-11-20T11:00:31+01:00 summary: bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) files: M Modules/_tracemalloc.c diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 211c6fbb8bcef..70219721b51cd 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1656,8 +1656,10 @@ PyInit__tracemalloc(void) if (m == NULL) return NULL; - if (tracemalloc_init() < 0) + if (tracemalloc_init() < 0) { + Py_DECREF(m); return NULL; + } return m; } From webhook-mailer at python.org Wed Nov 20 05:15:26 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 10:15:26 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in marshal init error path (GH-17260) Message-ID: https://github.com/python/cpython/commit/63f09e7628bd72f1bb2106226655b1f775757806 commit: 63f09e7628bd72f1bb2106226655b1f775757806 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T02:15:22-08:00 summary: bpo-38823: Fix refleak in marshal init error path (GH-17260) (cherry picked from commit 33b671e72450bf4b5a946ce0dde6b7fe21150108) Co-authored-by: Brandt Bucher files: M Python/marshal.c diff --git a/Python/marshal.c b/Python/marshal.c index 7d60614e712ae..2e911b7be2759 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1860,6 +1860,9 @@ PyMarshal_Init(void) PyObject *mod = PyModule_Create(&marshalmodule); if (mod == NULL) return NULL; - PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + Py_DECREF(mod); + return NULL; + } return mod; } From webhook-mailer at python.org Wed Nov 20 05:16:11 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 10:16:11 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in marshal init error path (GH-17260) Message-ID: https://github.com/python/cpython/commit/2ea4c37c1ecf05a8495211d55ed6888439b1b9cf commit: 2ea4c37c1ecf05a8495211d55ed6888439b1b9cf branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T02:16:02-08:00 summary: bpo-38823: Fix refleak in marshal init error path (GH-17260) (cherry picked from commit 33b671e72450bf4b5a946ce0dde6b7fe21150108) Co-authored-by: Brandt Bucher files: M Python/marshal.c diff --git a/Python/marshal.c b/Python/marshal.c index b2daff2c8a3be..c6a06e8c23976 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -1829,6 +1829,9 @@ PyMarshal_Init(void) PyObject *mod = PyModule_Create(&marshalmodule); if (mod == NULL) return NULL; - PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); + if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) { + Py_DECREF(mod); + return NULL; + } return mod; } From webhook-mailer at python.org Wed Nov 20 05:17:22 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 10:17:22 -0000 Subject: [Python-checkins] bpo-36854: Clear the current thread later (GH-17279) Message-ID: https://github.com/python/cpython/commit/9da7430675ceaeae5abeb9c9f7cd552b71b3a93a commit: 9da7430675ceaeae5abeb9c9f7cd552b71b3a93a branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T11:17:17+01:00 summary: bpo-36854: Clear the current thread later (GH-17279) Clear the current thread later in the Python finalization. * The PyInterpreterState_Delete() function is now responsible to call PyThreadState_Swap(NULL). * The tstate_delete_common() function is now responsible to clear the "autoTSSKey" thread local storage and it only clears it once the thread state is fully cleared. It allows to still get the current thread from TSS in tstate_delete_common(). files: M Modules/_xxsubinterpretersmodule.c M Python/pylifecycle.c M Python/pystate.c diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 7842947e54ac5..4a6ffdd326678 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -2056,7 +2056,6 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) } // Destroy the interpreter. - //PyInterpreterState_Delete(interp); PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? PyThreadState *save_tstate = PyThreadState_Swap(tstate); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 2975b3ebd6651..73114df79cd8e 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1226,9 +1226,6 @@ finalize_interp_delete(PyThreadState *tstate, int is_main_interp) _PyGILState_Fini(tstate); } - /* Delete current thread. After this, many C API calls become crashy. */ - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(tstate->interp); } @@ -1577,9 +1574,9 @@ new_interpreter(PyThreadState **tstate_p) PyErr_PrintEx(0); PyThreadState_Clear(tstate); - PyThreadState_Swap(save_tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); + PyThreadState_Swap(save_tstate); *tstate_p = NULL; return _PyStatus_OK(); diff --git a/Python/pystate.c b/Python/pystate.c index 8fff161dac0f5..93f0ce798888d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,6 +39,7 @@ extern "C" { /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); +static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); static PyStatus @@ -295,13 +296,13 @@ PyInterpreterState_Clear(PyInterpreterState *interp) static void -zapthreads(PyInterpreterState *interp) +zapthreads(PyInterpreterState *interp, int check_current) { - PyThreadState *p; + PyThreadState *tstate; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ - while ((p = interp->tstate_head) != NULL) { - PyThreadState_Delete(p); + while ((tstate = interp->tstate_head) != NULL) { + _PyThreadState_Delete(tstate, check_current); } } @@ -311,7 +312,11 @@ PyInterpreterState_Delete(PyInterpreterState *interp) { _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(interp); + zapthreads(interp, 0); + + /* Delete current thread. After this, many C API calls become crashy. */ + _PyThreadState_Swap(&runtime->gilstate, NULL); + HEAD_LOCK(runtime); PyInterpreterState **p; for (p = &interpreters->head; ; p = &(*p)->next) { @@ -367,7 +372,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) } PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp); + zapthreads(interp, 1); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -793,7 +798,8 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate) +tstate_delete_common(PyThreadState *tstate, + struct _gilstate_runtime_state *gilstate) { _PyRuntimeState *runtime = tstate->interp->runtime; if (tstate == NULL) { @@ -815,22 +821,32 @@ tstate_delete_common(PyThreadState *tstate) tstate->on_delete(tstate->on_delete_data); } PyMem_RawFree(tstate); -} - -void -PyThreadState_Delete(PyThreadState *tstate) -{ - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { - Py_FatalError("PyThreadState_Delete: tstate is still current"); - } if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - tstate_delete_common(tstate); +} + + +static void +_PyThreadState_Delete(PyThreadState *tstate, int check_current) +{ + struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; + if (check_current) { + if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { + Py_FatalError("PyThreadState_Delete: tstate is still current"); + } + } + tstate_delete_common(tstate, gilstate); +} + + +void +PyThreadState_Delete(PyThreadState *tstate) +{ + _PyThreadState_Delete(tstate, 1); } @@ -842,12 +858,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(tstate); - if (gilstate->autoInterpreterState && - PyThread_tss_get(&gilstate->autoTSSkey) == tstate) - { - PyThread_tss_set(&gilstate->autoTSSkey, NULL); - } + tstate_delete_common(tstate, gilstate); _PyRuntimeGILState_SetThreadState(gilstate, NULL); PyEval_ReleaseLock(); } From webhook-mailer at python.org Wed Nov 20 05:27:08 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 10:27:08 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) Message-ID: https://github.com/python/cpython/commit/1d7245c3e0cfe4508855c5025b25d8894155ecc5 commit: 1d7245c3e0cfe4508855c5025b25d8894155ecc5 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T02:26:54-08:00 summary: bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) (cherry picked from commit d51a363a4379385fdfe9c09a56324631465ede29) Co-authored-by: Brandt Bucher files: M Modules/_tracemalloc.c diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 7f19c5598120e..1fe72a8a4627b 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1655,8 +1655,10 @@ PyInit__tracemalloc(void) if (m == NULL) return NULL; - if (tracemalloc_init() < 0) + if (tracemalloc_init() < 0) { + Py_DECREF(m); return NULL; + } return m; } From webhook-mailer at python.org Wed Nov 20 05:27:08 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 10:27:08 -0000 Subject: [Python-checkins] bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) Message-ID: https://github.com/python/cpython/commit/daf7a082b20e59a0518cda1500add42c36ab058f commit: daf7a082b20e59a0518cda1500add42c36ab058f branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T02:26:48-08:00 summary: bpo-38823: Fix refleak in _tracemalloc init error handling (GH-17235) (cherry picked from commit d51a363a4379385fdfe9c09a56324631465ede29) Co-authored-by: Brandt Bucher files: M Modules/_tracemalloc.c diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index ee32ac29b7eea..cbcf55f817435 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1637,8 +1637,10 @@ PyInit__tracemalloc(void) if (m == NULL) return NULL; - if (tracemalloc_init() < 0) + if (tracemalloc_init() < 0) { + Py_DECREF(m); return NULL; + } return m; } From webhook-mailer at python.org Wed Nov 20 05:48:23 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 10:48:23 -0000 Subject: [Python-checkins] bpo-36854: gcmodule.c gets its state from tstate (GH-17285) Message-ID: https://github.com/python/cpython/commit/67e0de6f0b060ac8f373952f0ca4b3117ad5b611 commit: 67e0de6f0b060ac8f373952f0ca4b3117ad5b611 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T11:48:18+01:00 summary: bpo-36854: gcmodule.c gets its state from tstate (GH-17285) * Add GCState type for readability * gcmodule.c now gets its gcstate from tstate * _PyGC_DumpShutdownStats() now expects tstate rather than runtime * Rename "state" to "gcstate" for readability: to avoid confusion between "state" and "tstate" for example. * collect() now only expects tstate: it gets gcstate from tstate. * Pass tstate to _PyErr_xxx() functions files: M Include/internal/pycore_object.h M Include/internal/pycore_pylifecycle.h M Modules/gcmodule.c M Python/import.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 0ae5995848626..46555218bc5ea 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -18,7 +18,7 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); * NB: While the object is tracked by the collector, it must be safe to call the * ob_traverse method. * - * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags + * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags * because it's not object header. So we don't use _PyGCHead_PREV() and * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. * @@ -37,11 +37,13 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, "object is in generation which is garbage collected", filename, lineno, "_PyObject_GC_TRACK"); - PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0->_gc_prev); + PyThreadState *tstate = _PyThreadState_GET(); + PyGC_Head *generation0 = tstate->interp->runtime->gc.generation0; + PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT(last, gc); _PyGCHead_SET_PREV(gc, last); - _PyGCHead_SET_NEXT(gc, _PyRuntime.gc.generation0); - _PyRuntime.gc.generation0->_gc_prev = (uintptr_t)gc; + _PyGCHead_SET_NEXT(gc, generation0); + generation0->_gc_prev = (uintptr_t)gc; } #define _PyObject_GC_TRACK(op) \ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index b2f2ad841c8e0..b8d5e361b3c73 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -89,7 +89,7 @@ extern void _PyWarnings_Fini(PyInterpreterState *interp); extern void _PyGILState_Init(PyThreadState *tstate); extern void _PyGILState_Fini(PyThreadState *tstate); -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(struct pyruntimestate *runtime); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyThreadState *tstate); PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv( const PyPreConfig *src_config, diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 518b0547d2745..6fce9a8a0b6d7 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -34,6 +34,8 @@ #include "pydtrace.h" #include "pytime.h" /* for _PyTime_GetMonotonicClock() */ +typedef struct _gc_runtime_state GCState; + /*[clinic input] module gc [clinic start generated code]*/ @@ -128,14 +130,14 @@ static PyObject *gc_str = NULL; DEBUG_UNCOLLECTABLE | \ DEBUG_SAVEALL -#define GEN_HEAD(state, n) (&(state)->generations[n].head) +#define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) void -_PyGC_InitializeRuntime(struct _gc_runtime_state *state) +_PyGC_InitializeRuntime(GCState *gcstate) { - state->enabled = 1; /* automatic collection enabled? */ + gcstate->enabled = 1; /* automatic collection enabled? */ -#define _GEN_HEAD(n) GEN_HEAD(state, n) +#define _GEN_HEAD(n) GEN_HEAD(gcstate, n) struct gc_generation generations[NUM_GENERATIONS] = { /* PyGC_Head, threshold, count */ {{(uintptr_t)_GEN_HEAD(0), (uintptr_t)_GEN_HEAD(0)}, 700, 0}, @@ -143,24 +145,24 @@ _PyGC_InitializeRuntime(struct _gc_runtime_state *state) {{(uintptr_t)_GEN_HEAD(2), (uintptr_t)_GEN_HEAD(2)}, 10, 0}, }; for (int i = 0; i < NUM_GENERATIONS; i++) { - state->generations[i] = generations[i]; + gcstate->generations[i] = generations[i]; }; - state->generation0 = GEN_HEAD(state, 0); + gcstate->generation0 = GEN_HEAD(gcstate, 0); struct gc_generation permanent_generation = { - {(uintptr_t)&state->permanent_generation.head, - (uintptr_t)&state->permanent_generation.head}, 0, 0 + {(uintptr_t)&gcstate->permanent_generation.head, + (uintptr_t)&gcstate->permanent_generation.head}, 0, 0 }; - state->permanent_generation = permanent_generation; + gcstate->permanent_generation = permanent_generation; } PyStatus _PyGC_Init(PyThreadState *tstate) { - struct _gc_runtime_state *state = &tstate->interp->runtime->gc; - if (state->garbage == NULL) { - state->garbage = PyList_New(0); - if (state->garbage == NULL) { + GCState *gcstate = &tstate->interp->runtime->gc; + if (gcstate->garbage == NULL) { + gcstate->garbage = PyList_New(0); + if (gcstate->garbage == NULL) { return _PyStatus_NO_MEMORY(); } } @@ -919,18 +921,18 @@ debug_cycle(const char *msg, PyObject *op) */ static void handle_legacy_finalizers(PyThreadState *tstate, - struct _gc_runtime_state *state, + GCState *gcstate, PyGC_Head *finalizers, PyGC_Head *old) { assert(!_PyErr_Occurred(tstate)); - assert(state->garbage != NULL); + assert(gcstate->garbage != NULL); PyGC_Head *gc = GC_NEXT(finalizers); for (; gc != finalizers; gc = GC_NEXT(gc)) { PyObject *op = FROM_GC(gc); - if ((state->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { - if (PyList_Append(state->garbage, op) < 0) { + if ((gcstate->debug & DEBUG_SAVEALL) || has_legacy_finalizer(op)) { + if (PyList_Append(gcstate->garbage, op) < 0) { _PyErr_Clear(tstate); break; } @@ -945,7 +947,7 @@ handle_legacy_finalizers(PyThreadState *tstate, * list, due to refcounts falling to 0. */ static void -finalize_garbage(PyGC_Head *collectable) +finalize_garbage(PyThreadState *tstate, PyGC_Head *collectable) { destructor finalize; PyGC_Head seen; @@ -969,7 +971,7 @@ finalize_garbage(PyGC_Head *collectable) _PyGCHead_SET_FINALIZED(gc); Py_INCREF(op); finalize(op); - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); Py_DECREF(op); } } @@ -981,7 +983,7 @@ finalize_garbage(PyGC_Head *collectable) * objects may be freed. It is possible I screwed something up here. */ static void -delete_garbage(PyThreadState *tstate, struct _gc_runtime_state *state, +delete_garbage(PyThreadState *tstate, GCState *gcstate, PyGC_Head *collectable, PyGC_Head *old) { assert(!_PyErr_Occurred(tstate)); @@ -993,9 +995,9 @@ delete_garbage(PyThreadState *tstate, struct _gc_runtime_state *state, _PyObject_ASSERT_WITH_MSG(op, Py_REFCNT(op) > 0, "refcount is too small"); - if (state->debug & DEBUG_SAVEALL) { - assert(state->garbage != NULL); - if (PyList_Append(state->garbage, op) < 0) { + if (gcstate->debug & DEBUG_SAVEALL) { + assert(gcstate->garbage != NULL); + if (PyList_Append(gcstate->garbage, op) < 0) { _PyErr_Clear(tstate); } } @@ -1042,7 +1044,7 @@ clear_freelists(void) // Show stats for objects in each gennerations. static void -show_stats_each_generations(struct _gc_runtime_state *state) +show_stats_each_generations(GCState *gcstate) { char buf[100]; size_t pos = 0; @@ -1050,13 +1052,13 @@ show_stats_each_generations(struct _gc_runtime_state *state) for (int i = 0; i < NUM_GENERATIONS && pos < sizeof(buf); i++) { pos += PyOS_snprintf(buf+pos, sizeof(buf)-pos, " %"PY_FORMAT_SIZE_T"d", - gc_list_size(GEN_HEAD(state, i))); + gc_list_size(GEN_HEAD(gcstate, i))); } PySys_FormatStderr( "gc: objects in each generation:%s\n" "gc: objects in permanent generation: %zd\n", - buf, gc_list_size(&state->permanent_generation.head)); + buf, gc_list_size(&gcstate->permanent_generation.head)); } /* Deduce wich objects among "base" are unreachable from outside the list @@ -1145,7 +1147,7 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable, /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t -collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, +collect(PyThreadState *tstate, int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail) { int i; @@ -1157,10 +1159,11 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ + GCState *gcstate = &tstate->interp->runtime->gc; - if (state->debug & DEBUG_STATS) { + if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); - show_stats_each_generations(state); + show_stats_each_generations(gcstate); t1 = _PyTime_GetMonotonicClock(); } @@ -1169,19 +1172,19 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, /* update collection and allocation counters */ if (generation+1 < NUM_GENERATIONS) - state->generations[generation+1].count += 1; + gcstate->generations[generation+1].count += 1; for (i = 0; i <= generation; i++) - state->generations[i].count = 0; + gcstate->generations[i].count = 0; /* merge younger generations with one we are currently collecting */ for (i = 0; i < generation; i++) { - gc_list_merge(GEN_HEAD(state, i), GEN_HEAD(state, generation)); + gc_list_merge(GEN_HEAD(gcstate, i), GEN_HEAD(gcstate, generation)); } /* handy references */ - young = GEN_HEAD(state, generation); + young = GEN_HEAD(gcstate, generation); if (generation < NUM_GENERATIONS-1) - old = GEN_HEAD(state, generation+1); + old = GEN_HEAD(gcstate, generation+1); else old = young; validate_list(old, collecting_clear_unreachable_clear); @@ -1192,7 +1195,7 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, /* Move reachable objects to next generation. */ if (young != old) { if (generation == NUM_GENERATIONS - 2) { - state->long_lived_pending += gc_list_size(young); + gcstate->long_lived_pending += gc_list_size(young); } gc_list_merge(young, old); } @@ -1200,8 +1203,8 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, /* We only untrack dicts in full collections, to avoid quadratic dict build-up. See issue #14775. */ untrack_dicts(young); - state->long_lived_pending = 0; - state->long_lived_total = gc_list_size(young); + gcstate->long_lived_pending = 0; + gcstate->long_lived_total = gc_list_size(young); } /* All objects in unreachable are trash, but objects reachable from @@ -1221,7 +1224,7 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, validate_list(&unreachable, collecting_set_unreachable_clear); /* Print debugging information. */ - if (state->debug & DEBUG_COLLECTABLE) { + if (gcstate->debug & DEBUG_COLLECTABLE) { for (gc = GC_NEXT(&unreachable); gc != &unreachable; gc = GC_NEXT(gc)) { debug_cycle("collectable", FROM_GC(gc)); } @@ -1234,7 +1237,7 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, validate_list(&unreachable, collecting_set_unreachable_clear); /* Call tp_finalize on objects which have one. */ - finalize_garbage(&unreachable); + finalize_garbage(tstate, &unreachable); /* Handle any objects that may have resurrected after the call * to 'finalize_garbage' and continue the collection with the @@ -1247,16 +1250,16 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, * in finalizers to be freed. */ m += gc_list_size(&final_unreachable); - delete_garbage(tstate, state, &final_unreachable, old); + delete_garbage(tstate, gcstate, &final_unreachable, old); /* Collect statistics on uncollectable objects found and print * debugging information. */ for (gc = GC_NEXT(&finalizers); gc != &finalizers; gc = GC_NEXT(gc)) { n++; - if (state->debug & DEBUG_UNCOLLECTABLE) + if (gcstate->debug & DEBUG_UNCOLLECTABLE) debug_cycle("uncollectable", FROM_GC(gc)); } - if (state->debug & DEBUG_STATS) { + if (gcstate->debug & DEBUG_STATS) { double d = _PyTime_AsSecondsDouble(_PyTime_GetMonotonicClock() - t1); PySys_WriteStderr( "gc: done, %" PY_FORMAT_SIZE_T "d unreachable, " @@ -1268,7 +1271,7 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, * reachable list of garbage. The programmer has to deal with * this if they insist on creating this type of structure. */ - handle_legacy_finalizers(tstate, state, &finalizers, old); + handle_legacy_finalizers(tstate, gcstate, &finalizers, old); validate_list(old, collecting_clear_unreachable_clear); /* Clear free list only during the collection of the highest @@ -1297,7 +1300,7 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, *n_uncollectable = n; } - struct gc_generation_stats *stats = &state->generation_stats[generation]; + struct gc_generation_stats *stats = &gcstate->generation_stats[generation]; stats->collections++; stats->collected += m; stats->uncollectable += n; @@ -1314,21 +1317,22 @@ collect(PyThreadState *tstate, struct _gc_runtime_state *state, int generation, * is starting or stopping */ static void -invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, +invoke_gc_callback(PyThreadState *tstate, const char *phase, int generation, Py_ssize_t collected, Py_ssize_t uncollectable) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); /* we may get called very early */ - if (state->callbacks == NULL) { + GCState *gcstate = &tstate->interp->runtime->gc; + if (gcstate->callbacks == NULL) { return; } /* The local variable cannot be rebound, check it for sanity */ - assert(PyList_CheckExact(state->callbacks)); + assert(PyList_CheckExact(gcstate->callbacks)); PyObject *info = NULL; - if (PyList_GET_SIZE(state->callbacks) != 0) { + if (PyList_GET_SIZE(gcstate->callbacks) != 0) { info = Py_BuildValue("{sisnsn}", "generation", generation, "collected", collected, @@ -1338,8 +1342,8 @@ invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, return; } } - for (Py_ssize_t i=0; icallbacks); i++) { - PyObject *r, *cb = PyList_GET_ITEM(state->callbacks, i); + for (Py_ssize_t i=0; icallbacks); i++) { + PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); Py_INCREF(cb); /* make sure cb doesn't go away */ r = PyObject_CallFunction(cb, "sO", phase, info); if (r == NULL) { @@ -1351,42 +1355,42 @@ invoke_gc_callback(struct _gc_runtime_state *state, const char *phase, Py_DECREF(cb); } Py_XDECREF(info); - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); } /* Perform garbage collection of a generation and invoke * progress callbacks. */ static Py_ssize_t -collect_with_callback(PyThreadState *tstate, struct _gc_runtime_state *state, - int generation) +collect_with_callback(PyThreadState *tstate, int generation) { - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); Py_ssize_t result, collected, uncollectable; - invoke_gc_callback(state, "start", generation, 0, 0); - result = collect(tstate, state, generation, &collected, &uncollectable, 0); - invoke_gc_callback(state, "stop", generation, collected, uncollectable); - assert(!PyErr_Occurred()); + invoke_gc_callback(tstate, "start", generation, 0, 0); + result = collect(tstate, generation, &collected, &uncollectable, 0); + invoke_gc_callback(tstate, "stop", generation, collected, uncollectable); + assert(!_PyErr_Occurred(tstate)); return result; } static Py_ssize_t -collect_generations(PyThreadState *tstate, struct _gc_runtime_state *state) +collect_generations(PyThreadState *tstate) { + GCState *gcstate = &tstate->interp->runtime->gc; /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ Py_ssize_t n = 0; for (int i = NUM_GENERATIONS-1; i >= 0; i--) { - if (state->generations[i].count > state->generations[i].threshold) { + if (gcstate->generations[i].count > gcstate->generations[i].threshold) { /* Avoid quadratic performance degradation in number of tracked objects. See comments at the beginning of this file, and issue #4074. */ if (i == NUM_GENERATIONS - 1 - && state->long_lived_pending < state->long_lived_total / 4) + && gcstate->long_lived_pending < gcstate->long_lived_total / 4) continue; - n = collect_with_callback(tstate, state, i); + n = collect_with_callback(tstate, i); break; } } @@ -1405,7 +1409,9 @@ static PyObject * gc_enable_impl(PyObject *module) /*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ { - _PyRuntime.gc.enabled = 1; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + gcstate->enabled = 1; Py_RETURN_NONE; } @@ -1419,7 +1425,9 @@ static PyObject * gc_disable_impl(PyObject *module) /*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ { - _PyRuntime.gc.enabled = 0; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + gcstate->enabled = 0; Py_RETURN_NONE; } @@ -1433,7 +1441,9 @@ static int gc_isenabled_impl(PyObject *module) /*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ { - return _PyRuntime.gc.enabled; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + return gcstate->enabled; } /*[clinic input] @@ -1461,16 +1471,16 @@ gc_collect_impl(PyObject *module, int generation) return -1; } - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; Py_ssize_t n; - if (state->collecting) { + if (gcstate->collecting) { /* already collecting, don't do anything */ n = 0; } else { - state->collecting = 1; - n = collect_with_callback(tstate, state, generation); - state->collecting = 0; + gcstate->collecting = 1; + n = collect_with_callback(tstate, generation); + gcstate->collecting = 0; } return n; } @@ -1497,8 +1507,9 @@ static PyObject * gc_set_debug_impl(PyObject *module, int flags) /*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ { - _PyRuntime.gc.debug = flags; - + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + gcstate->debug = flags; Py_RETURN_NONE; } @@ -1512,7 +1523,9 @@ static int gc_get_debug_impl(PyObject *module) /*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ { - return _PyRuntime.gc.debug; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + return gcstate->debug; } PyDoc_STRVAR(gc_set_thresh__doc__, @@ -1524,15 +1537,16 @@ PyDoc_STRVAR(gc_set_thresh__doc__, static PyObject * gc_set_threshold(PyObject *self, PyObject *args) { - struct _gc_runtime_state *state = &_PyRuntime.gc; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; if (!PyArg_ParseTuple(args, "i|ii:set_threshold", - &state->generations[0].threshold, - &state->generations[1].threshold, - &state->generations[2].threshold)) + &gcstate->generations[0].threshold, + &gcstate->generations[1].threshold, + &gcstate->generations[2].threshold)) return NULL; for (int i = 3; i < NUM_GENERATIONS; i++) { /* generations higher than 2 get the same threshold */ - state->generations[i].threshold = state->generations[2].threshold; + gcstate->generations[i].threshold = gcstate->generations[2].threshold; } Py_RETURN_NONE; } @@ -1547,11 +1561,12 @@ static PyObject * gc_get_threshold_impl(PyObject *module) /*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ { - struct _gc_runtime_state *state = &_PyRuntime.gc; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; return Py_BuildValue("(iii)", - state->generations[0].threshold, - state->generations[1].threshold, - state->generations[2].threshold); + gcstate->generations[0].threshold, + gcstate->generations[1].threshold, + gcstate->generations[2].threshold); } /*[clinic input] @@ -1564,11 +1579,12 @@ static PyObject * gc_get_count_impl(PyObject *module) /*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ { - struct _gc_runtime_state *state = &_PyRuntime.gc; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; return Py_BuildValue("(iii)", - state->generations[0].count, - state->generations[1].count, - state->generations[2].count); + gcstate->generations[0].count, + gcstate->generations[1].count, + gcstate->generations[2].count); } static int @@ -1607,13 +1623,16 @@ Return the list of objects that directly refer to any of objs."); static PyObject * gc_get_referrers(PyObject *self, PyObject *args) { + PyThreadState *tstate = _PyThreadState_GET(); int i; PyObject *result = PyList_New(0); - if (!result) return NULL; + if (!result) { + return NULL; + } - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; for (i = 0; i < NUM_GENERATIONS; i++) { - if (!(gc_referrers_for(args, GEN_HEAD(state, i), result))) { + if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { Py_DECREF(result); return NULL; } @@ -1673,9 +1692,10 @@ static PyObject * gc_get_objects_impl(PyObject *module, Py_ssize_t generation) /*[clinic end generated code: output=48b35fea4ba6cb0e input=ef7da9df9806754c]*/ { + PyThreadState *tstate = _PyThreadState_GET(); int i; PyObject* result; - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; result = PyList_New(0); if (result == NULL) { @@ -1685,20 +1705,20 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) /* If generation is passed, we extract only that generation */ if (generation != -1) { if (generation >= NUM_GENERATIONS) { - PyErr_Format(PyExc_ValueError, - "generation parameter must be less than the number of " - "available generations (%i)", - NUM_GENERATIONS); + _PyErr_Format(tstate, PyExc_ValueError, + "generation parameter must be less than the number of " + "available generations (%i)", + NUM_GENERATIONS); goto error; } if (generation < 0) { - PyErr_SetString(PyExc_ValueError, - "generation parameter cannot be negative"); + _PyErr_SetString(tstate, PyExc_ValueError, + "generation parameter cannot be negative"); goto error; } - if (append_objects(result, GEN_HEAD(state, generation))) { + if (append_objects(result, GEN_HEAD(gcstate, generation))) { goto error; } @@ -1707,7 +1727,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) /* If generation is not passed or None, get all objects from all generations */ for (i = 0; i < NUM_GENERATIONS; i++) { - if (append_objects(result, GEN_HEAD(state, i))) { + if (append_objects(result, GEN_HEAD(gcstate, i))) { goto error; } } @@ -1730,12 +1750,13 @@ gc_get_stats_impl(PyObject *module) { int i; struct gc_generation_stats stats[NUM_GENERATIONS], *st; + PyThreadState *tstate = _PyThreadState_GET(); /* To get consistent values despite allocations while constructing the result list, we use a snapshot of the running stats. */ - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; for (i = 0; i < NUM_GENERATIONS; i++) { - stats[i] = state->generation_stats[i]; + stats[i] = gcstate->generation_stats[i]; } PyObject *result = PyList_New(0); @@ -1805,10 +1826,11 @@ static PyObject * gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { - struct _gc_runtime_state *state = &_PyRuntime.gc; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; for (int i = 0; i < NUM_GENERATIONS; ++i) { - gc_list_merge(GEN_HEAD(state, i), &state->permanent_generation.head); - state->generations[i].count = 0; + gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); + gcstate->generations[i].count = 0; } Py_RETURN_NONE; } @@ -1825,8 +1847,10 @@ static PyObject * gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { - struct _gc_runtime_state *state = &_PyRuntime.gc; - gc_list_merge(&state->permanent_generation.head, GEN_HEAD(state, NUM_GENERATIONS-1)); + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + gc_list_merge(&gcstate->permanent_generation.head, + GEN_HEAD(gcstate, NUM_GENERATIONS-1)); Py_RETURN_NONE; } @@ -1840,7 +1864,9 @@ static Py_ssize_t gc_get_freeze_count_impl(PyObject *module) /*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ { - return gc_list_size(&_PyRuntime.gc.permanent_generation.head); + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + return gc_list_size(&gcstate->permanent_generation.head); } @@ -1911,23 +1937,23 @@ PyInit_gc(void) return NULL; } - struct _gc_runtime_state *state = &_PyRuntime.gc; - if (state->garbage == NULL) { - state->garbage = PyList_New(0); - if (state->garbage == NULL) + GCState *gcstate = &_PyRuntime.gc; + if (gcstate->garbage == NULL) { + gcstate->garbage = PyList_New(0); + if (gcstate->garbage == NULL) return NULL; } - Py_INCREF(state->garbage); - if (PyModule_AddObject(m, "garbage", state->garbage) < 0) + Py_INCREF(gcstate->garbage); + if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) return NULL; - if (state->callbacks == NULL) { - state->callbacks = PyList_New(0); - if (state->callbacks == NULL) + if (gcstate->callbacks == NULL) { + gcstate->callbacks = PyList_New(0); + if (gcstate->callbacks == NULL) return NULL; } - Py_INCREF(state->callbacks); - if (PyModule_AddObject(m, "callbacks", state->callbacks) < 0) + Py_INCREF(gcstate->callbacks); + if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) return NULL; #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL @@ -1945,24 +1971,24 @@ Py_ssize_t PyGC_Collect(void) { PyThreadState *tstate = _PyThreadState_GET(); - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; - if (!state->enabled) { + if (!gcstate->enabled) { return 0; } Py_ssize_t n; - if (state->collecting) { + if (gcstate->collecting) { /* already collecting, don't do anything */ n = 0; } else { PyObject *exc, *value, *tb; - state->collecting = 1; + gcstate->collecting = 1; _PyErr_Fetch(tstate, &exc, &value, &tb); - n = collect_with_callback(tstate, state, NUM_GENERATIONS - 1); + n = collect_with_callback(tstate, NUM_GENERATIONS - 1); _PyErr_Restore(tstate, exc, value, tb); - state->collecting = 0; + gcstate->collecting = 0; } return n; @@ -1980,7 +2006,7 @@ _PyGC_CollectNoFail(void) PyThreadState *tstate = _PyThreadState_GET(); assert(!_PyErr_Occurred(tstate)); - struct _gc_runtime_state *state = &_PyRuntime.gc; + GCState *gcstate = &tstate->interp->runtime->gc; Py_ssize_t n; /* Ideally, this function is only called on interpreter shutdown, @@ -1989,25 +2015,25 @@ _PyGC_CollectNoFail(void) during interpreter shutdown (and then never finish it). See http://bugs.python.org/issue8713#msg195178 for an example. */ - if (state->collecting) { + if (gcstate->collecting) { n = 0; } else { - state->collecting = 1; - n = collect(tstate, state, NUM_GENERATIONS - 1, NULL, NULL, 1); - state->collecting = 0; + gcstate->collecting = 1; + n = collect(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1); + gcstate->collecting = 0; } return n; } void -_PyGC_DumpShutdownStats(_PyRuntimeState *runtime) +_PyGC_DumpShutdownStats(PyThreadState *tstate) { - struct _gc_runtime_state *state = &runtime->gc; - if (!(state->debug & DEBUG_SAVEALL) - && state->garbage != NULL && PyList_GET_SIZE(state->garbage) > 0) { + GCState *gcstate = &tstate->interp->runtime->gc; + if (!(gcstate->debug & DEBUG_SAVEALL) + && gcstate->garbage != NULL && PyList_GET_SIZE(gcstate->garbage) > 0) { const char *message; - if (state->debug & DEBUG_UNCOLLECTABLE) + if (gcstate->debug & DEBUG_UNCOLLECTABLE) message = "gc: %zd uncollectable objects at " \ "shutdown"; else @@ -2018,13 +2044,13 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime) already. */ if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0, "gc", NULL, message, - PyList_GET_SIZE(state->garbage))) + PyList_GET_SIZE(gcstate->garbage))) PyErr_WriteUnraisable(NULL); - if (state->debug & DEBUG_UNCOLLECTABLE) { + if (gcstate->debug & DEBUG_UNCOLLECTABLE) { PyObject *repr = NULL, *bytes = NULL; - repr = PyObject_Repr(state->garbage); + repr = PyObject_Repr(gcstate->garbage); if (!repr || !(bytes = PyUnicode_EncodeFSDefault(repr))) - PyErr_WriteUnraisable(state->garbage); + PyErr_WriteUnraisable(gcstate->garbage); else { PySys_WriteStderr( " %s\n", @@ -2040,9 +2066,9 @@ _PyGC_DumpShutdownStats(_PyRuntimeState *runtime) void _PyGC_Fini(PyThreadState *tstate) { - struct _gc_runtime_state *state = &tstate->interp->runtime->gc; - Py_CLEAR(state->garbage); - Py_CLEAR(state->callbacks); + GCState *gcstate = &tstate->interp->runtime->gc; + Py_CLEAR(gcstate->garbage); + Py_CLEAR(gcstate->callbacks); } /* for debugging */ @@ -2104,9 +2130,10 @@ PyObject_GC_UnTrack(void *op_raw) static PyObject * _PyObject_GC_Alloc(int use_calloc, size_t basicsize) { - struct _gc_runtime_state *state = &_PyRuntime.gc; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { - return PyErr_NoMemory(); + return _PyErr_NoMemory(tstate); } size_t size = sizeof(PyGC_Head) + basicsize; @@ -2118,23 +2145,22 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize) g = (PyGC_Head *)PyObject_Malloc(size); } if (g == NULL) { - return PyErr_NoMemory(); + return _PyErr_NoMemory(tstate); } assert(((uintptr_t)g & 3) == 0); // g must be aligned 4bytes boundary g->_gc_next = 0; g->_gc_prev = 0; - state->generations[0].count++; /* number of allocated GC objects */ - if (state->generations[0].count > state->generations[0].threshold && - state->enabled && - state->generations[0].threshold && - !state->collecting && - !PyErr_Occurred()) + gcstate->generations[0].count++; /* number of allocated GC objects */ + if (gcstate->generations[0].count > gcstate->generations[0].threshold && + gcstate->enabled && + gcstate->generations[0].threshold && + !gcstate->collecting && + !_PyErr_Occurred(tstate)) { - PyThreadState *tstate = _PyThreadState_GET(); - state->collecting = 1; - collect_generations(tstate, state); - state->collecting = 0; + gcstate->collecting = 1; + collect_generations(tstate); + gcstate->collecting = 0; } PyObject *op = FROM_GC(g); return op; @@ -2203,9 +2229,10 @@ PyObject_GC_Del(void *op) if (_PyObject_GC_IS_TRACKED(op)) { gc_list_remove(g); } - struct _gc_runtime_state *state = &_PyRuntime.gc; - if (state->generations[0].count > 0) { - state->generations[0].count--; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->runtime->gc; + if (gcstate->generations[0].count > 0) { + gcstate->generations[0].count--; } PyObject_FREE(g); } diff --git a/Python/import.c b/Python/import.c index cbd0fa86fb58f..ac3d10cfed226 100644 --- a/Python/import.c +++ b/Python/import.c @@ -583,7 +583,7 @@ _PyImport_Cleanup(PyThreadState *tstate) _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ - _PyGC_DumpShutdownStats(&_PyRuntime); + _PyGC_DumpShutdownStats(tstate); /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end From webhook-mailer at python.org Wed Nov 20 06:08:42 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 11:08:42 -0000 Subject: [Python-checkins] bpo-38858: Fix reference leak in pycore_init_types() (GH-17286) Message-ID: https://github.com/python/cpython/commit/e7e699e4df73420ddccaa0057cd07ebb3b590b9b commit: e7e699e4df73420ddccaa0057cd07ebb3b590b9b branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T12:08:13+01:00 summary: bpo-38858: Fix reference leak in pycore_init_types() (GH-17286) Only call _PyGC_Init(), _PyExc_Init() and _PyErr_Init() in new_interpreter(). files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 73114df79cd8e..41b9596b60d01 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -558,7 +558,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_types(PyThreadState *tstate) +pycore_init_types(PyThreadState *tstate, int is_main_interp) { PyStatus status; @@ -567,18 +567,20 @@ pycore_init_types(PyThreadState *tstate) return status; } - status = _PyTypes_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + if (is_main_interp) { + status = _PyTypes_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } - if (!_PyLong_Init()) { - return _PyStatus_ERR("can't init longs"); - } + if (!_PyLong_Init()) { + return _PyStatus_ERR("can't init longs"); + } - status = _PyUnicode_Init(); - if (_PyStatus_EXCEPTION(status)) { - return status; + status = _PyUnicode_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } status = _PyExc_Init(); @@ -586,12 +588,14 @@ pycore_init_types(PyThreadState *tstate) return status; } - if (!_PyFloat_Init()) { - return _PyStatus_ERR("can't init float"); - } + if (is_main_interp) { + if (!_PyFloat_Init()) { + return _PyStatus_ERR("can't init float"); + } - if (_PyStructSequence_Init() < 0) { - return _PyStatus_ERR("can't initialize structseq"); + if (_PyStructSequence_Init() < 0) { + return _PyStatus_ERR("can't initialize structseq"); + } } status = _PyErr_Init(); @@ -599,8 +603,10 @@ pycore_init_types(PyThreadState *tstate) return status; } - if (!_PyContext_Init()) { - return _PyStatus_ERR("can't init context"); + if (is_main_interp) { + if (!_PyContext_Init()) { + return _PyStatus_ERR("can't init context"); + } } return _PyStatus_OK(); @@ -690,7 +696,7 @@ pyinit_config(_PyRuntimeState *runtime, config = &tstate->interp->config; *tstate_p = tstate; - status = pycore_init_types(tstate); + status = pycore_init_types(tstate, 1); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1477,7 +1483,7 @@ new_interpreter(PyThreadState **tstate_p) } config = &interp->config; - status = pycore_init_types(tstate); + status = pycore_init_types(tstate, 0); /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); From webhook-mailer at python.org Wed Nov 20 06:17:14 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 11:17:14 -0000 Subject: [Python-checkins] bpo-38835: Exclude PyFPE macros from the stable API (GH-17228) Message-ID: https://github.com/python/cpython/commit/488d02a24142948bfb1fafd19fa48e61fcbbabc5 commit: 488d02a24142948bfb1fafd19fa48e61fcbbabc5 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T12:17:09+01:00 summary: bpo-38835: Exclude PyFPE macros from the stable API (GH-17228) Exclude PyFPE_START_PROTECT() and PyFPE_END_PROTECT() macros of pyfpe.h from Py_LIMITED_API (stable API). files: A Misc/NEWS.d/next/C API/2019-11-18-15-38-23.bpo-38835.II8Szd.rst M Doc/whatsnew/3.9.rst M Include/pyfpe.h diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index ce1d3e0e96a58..542a031960013 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -226,6 +226,10 @@ Build and C API Changes and refers to a constant string. (Contributed by Serhiy Storchaka in :issue:`38650`.) +* Exclude ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` macros of + ``pyfpe.h`` from ``Py_LIMITED_API`` (stable API). + (Contributed by Victor Stinner in :issue:`38835`.) + Deprecated ========== diff --git a/Include/pyfpe.h b/Include/pyfpe.h index 5a99e3979311f..cc2def63aa552 100644 --- a/Include/pyfpe.h +++ b/Include/pyfpe.h @@ -1,5 +1,7 @@ #ifndef Py_PYFPE_H #define Py_PYFPE_H +/* Header excluded from the stable API */ +#ifndef Py_LIMITED_API /* These macros used to do something when Python was built with --with-fpectl, * but support for that was dropped in 3.7. We continue to define them though, @@ -9,4 +11,5 @@ #define PyFPE_START_PROTECT(err_string, leave_stmt) #define PyFPE_END_PROTECT(v) +#endif /* !defined(Py_LIMITED_API) */ #endif /* !Py_PYFPE_H */ diff --git a/Misc/NEWS.d/next/C API/2019-11-18-15-38-23.bpo-38835.II8Szd.rst b/Misc/NEWS.d/next/C API/2019-11-18-15-38-23.bpo-38835.II8Szd.rst new file mode 100644 index 0000000000000..2bb84dc19b6ff --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-18-15-38-23.bpo-38835.II8Szd.rst @@ -0,0 +1,2 @@ +Exclude ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` macros of +``pyfpe.h`` from ``Py_LIMITED_API`` (stable API). From webhook-mailer at python.org Wed Nov 20 06:25:56 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 11:25:56 -0000 Subject: [Python-checkins] bpo-36854: Move _PyRuntimeState.gc to PyInterpreterState (GH-17287) Message-ID: https://github.com/python/cpython/commit/7247407c35330f3f6292f1d40606b7ba6afd5700 commit: 7247407c35330f3f6292f1d40606b7ba6afd5700 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T12:25:50+01:00 summary: bpo-36854: Move _PyRuntimeState.gc to PyInterpreterState (GH-17287) * Rename _PyGC_InitializeRuntime() to _PyGC_InitState() * finalize_interp_clear() now also calls _PyGC_Fini() in subinterpreters (clear the GC state). files: A Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst M Include/internal/pycore_object.h M Include/internal/pycore_pymem.h M Include/internal/pycore_pystate.h M Modules/gcmodule.c M Objects/object.c M Python/pylifecycle.c M Python/pystate.c diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 46555218bc5ea..ba6636d7f8cfc 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -38,7 +38,7 @@ static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, filename, lineno, "_PyObject_GC_TRACK"); PyThreadState *tstate = _PyThreadState_GET(); - PyGC_Head *generation0 = tstate->interp->runtime->gc.generation0; + PyGC_Head *generation0 = tstate->interp->gc.generation0; PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); _PyGCHead_SET_NEXT(last, gc); _PyGCHead_SET_PREV(gc, last); diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 97d8fd99904a7..a4e972068348c 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -144,7 +144,7 @@ struct _gc_runtime_state { Py_ssize_t long_lived_pending; }; -PyAPI_FUNC(void) _PyGC_InitializeRuntime(struct _gc_runtime_state *); +PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); /* Set the memory allocator of the specified domain to the default. diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index fec64a7badba1..0c3c1e3df34de 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -74,6 +74,8 @@ struct _is { int finalizing; + struct _gc_runtime_state gc; + PyObject *modules; PyObject *modules_by_index; PyObject *sysdict; @@ -130,9 +132,7 @@ struct _is { struct _warnings_runtime_state warnings; PyObject *audit_hooks; -/* - * See bpo-36876: miscellaneous ad hoc statics have been moved here. - */ + struct { struct { int level; @@ -239,7 +239,6 @@ typedef struct pyruntimestate { void (*exitfuncs[NEXITFUNCS])(void); int nexitfuncs; - struct _gc_runtime_state gc; struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst new file mode 100644 index 0000000000000..2b4d5b3bc8590 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-20-12-01-37.bpo-36854.Zga_md.rst @@ -0,0 +1,3 @@ +The garbage collector state becomes per interpreter +(``PyInterpreterState.gc``), rather than being global +(``_PyRuntimeState.gc``). diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 6fce9a8a0b6d7..967bbe9c0d45d 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -133,7 +133,7 @@ static PyObject *gc_str = NULL; #define GEN_HEAD(gcstate, n) (&(gcstate)->generations[n].head) void -_PyGC_InitializeRuntime(GCState *gcstate) +_PyGC_InitState(GCState *gcstate) { gcstate->enabled = 1; /* automatic collection enabled? */ @@ -159,7 +159,7 @@ _PyGC_InitializeRuntime(GCState *gcstate) PyStatus _PyGC_Init(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (gcstate->garbage == NULL) { gcstate->garbage = PyList_New(0); if (gcstate->garbage == NULL) { @@ -1159,7 +1159,7 @@ collect(PyThreadState *tstate, int generation, PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (gcstate->debug & DEBUG_STATS) { PySys_WriteStderr("gc: collecting generation %d...\n", generation); @@ -1324,7 +1324,7 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase, assert(!_PyErr_Occurred(tstate)); /* we may get called very early */ - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (gcstate->callbacks == NULL) { return; } @@ -1376,7 +1376,7 @@ collect_with_callback(PyThreadState *tstate, int generation) static Py_ssize_t collect_generations(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ @@ -1410,7 +1410,7 @@ gc_enable_impl(PyObject *module) /*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; gcstate->enabled = 1; Py_RETURN_NONE; } @@ -1426,7 +1426,7 @@ gc_disable_impl(PyObject *module) /*[clinic end generated code: output=97d1030f7aa9d279 input=8c2e5a14e800d83b]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; gcstate->enabled = 0; Py_RETURN_NONE; } @@ -1442,7 +1442,7 @@ gc_isenabled_impl(PyObject *module) /*[clinic end generated code: output=1874298331c49130 input=30005e0422373b31]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; return gcstate->enabled; } @@ -1471,7 +1471,7 @@ gc_collect_impl(PyObject *module, int generation) return -1; } - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; Py_ssize_t n; if (gcstate->collecting) { /* already collecting, don't do anything */ @@ -1508,7 +1508,7 @@ gc_set_debug_impl(PyObject *module, int flags) /*[clinic end generated code: output=7c8366575486b228 input=5e5ce15e84fbed15]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; gcstate->debug = flags; Py_RETURN_NONE; } @@ -1524,7 +1524,7 @@ gc_get_debug_impl(PyObject *module) /*[clinic end generated code: output=91242f3506cd1e50 input=91a101e1c3b98366]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; return gcstate->debug; } @@ -1538,7 +1538,7 @@ static PyObject * gc_set_threshold(PyObject *self, PyObject *args) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &gcstate->generations[0].threshold, &gcstate->generations[1].threshold, @@ -1562,7 +1562,7 @@ gc_get_threshold_impl(PyObject *module) /*[clinic end generated code: output=7902bc9f41ecbbd8 input=286d79918034d6e6]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; return Py_BuildValue("(iii)", gcstate->generations[0].threshold, gcstate->generations[1].threshold, @@ -1580,7 +1580,7 @@ gc_get_count_impl(PyObject *module) /*[clinic end generated code: output=354012e67b16398f input=a392794a08251751]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; return Py_BuildValue("(iii)", gcstate->generations[0].count, gcstate->generations[1].count, @@ -1630,7 +1630,7 @@ gc_get_referrers(PyObject *self, PyObject *args) return NULL; } - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; for (i = 0; i < NUM_GENERATIONS; i++) { if (!(gc_referrers_for(args, GEN_HEAD(gcstate, i), result))) { Py_DECREF(result); @@ -1695,7 +1695,7 @@ gc_get_objects_impl(PyObject *module, Py_ssize_t generation) PyThreadState *tstate = _PyThreadState_GET(); int i; PyObject* result; - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; result = PyList_New(0); if (result == NULL) { @@ -1754,7 +1754,7 @@ gc_get_stats_impl(PyObject *module) /* To get consistent values despite allocations while constructing the result list, we use a snapshot of the running stats. */ - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; for (i = 0; i < NUM_GENERATIONS; i++) { stats[i] = gcstate->generation_stats[i]; } @@ -1827,7 +1827,7 @@ gc_freeze_impl(PyObject *module) /*[clinic end generated code: output=502159d9cdc4c139 input=b602b16ac5febbe5]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; for (int i = 0; i < NUM_GENERATIONS; ++i) { gc_list_merge(GEN_HEAD(gcstate, i), &gcstate->permanent_generation.head); gcstate->generations[i].count = 0; @@ -1848,7 +1848,7 @@ gc_unfreeze_impl(PyObject *module) /*[clinic end generated code: output=1c15f2043b25e169 input=2dd52b170f4cef6c]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; gc_list_merge(&gcstate->permanent_generation.head, GEN_HEAD(gcstate, NUM_GENERATIONS-1)); Py_RETURN_NONE; @@ -1865,7 +1865,7 @@ gc_get_freeze_count_impl(PyObject *module) /*[clinic end generated code: output=61cbd9f43aa032e1 input=45ffbc65cfe2a6ed]*/ { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; return gc_list_size(&gcstate->permanent_generation.head); } @@ -1929,34 +1929,38 @@ static struct PyModuleDef gcmodule = { PyMODINIT_FUNC PyInit_gc(void) { - PyObject *m; + PyThreadState *tstate = _PyThreadState_GET(); + GCState *gcstate = &tstate->interp->gc; - m = PyModule_Create(&gcmodule); + PyObject *m = PyModule_Create(&gcmodule); if (m == NULL) { return NULL; } - GCState *gcstate = &_PyRuntime.gc; if (gcstate->garbage == NULL) { gcstate->garbage = PyList_New(0); - if (gcstate->garbage == NULL) + if (gcstate->garbage == NULL) { return NULL; + } } Py_INCREF(gcstate->garbage); - if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) + if (PyModule_AddObject(m, "garbage", gcstate->garbage) < 0) { return NULL; + } if (gcstate->callbacks == NULL) { gcstate->callbacks = PyList_New(0); - if (gcstate->callbacks == NULL) + if (gcstate->callbacks == NULL) { return NULL; + } } Py_INCREF(gcstate->callbacks); - if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) + if (PyModule_AddObject(m, "callbacks", gcstate->callbacks) < 0) { return NULL; + } -#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL +#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) { return NULL; } ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_COLLECTABLE); ADD_INT(DEBUG_UNCOLLECTABLE); @@ -1971,7 +1975,7 @@ Py_ssize_t PyGC_Collect(void) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (!gcstate->enabled) { return 0; @@ -2006,7 +2010,7 @@ _PyGC_CollectNoFail(void) PyThreadState *tstate = _PyThreadState_GET(); assert(!_PyErr_Occurred(tstate)); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; Py_ssize_t n; /* Ideally, this function is only called on interpreter shutdown, @@ -2029,7 +2033,7 @@ _PyGC_CollectNoFail(void) void _PyGC_DumpShutdownStats(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (!(gcstate->debug & DEBUG_SAVEALL) && gcstate->garbage != NULL && PyList_GET_SIZE(gcstate->garbage) > 0) { const char *message; @@ -2066,7 +2070,7 @@ _PyGC_DumpShutdownStats(PyThreadState *tstate) void _PyGC_Fini(PyThreadState *tstate) { - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); } @@ -2131,7 +2135,7 @@ static PyObject * _PyObject_GC_Alloc(int use_calloc, size_t basicsize) { PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { return _PyErr_NoMemory(tstate); } @@ -2230,7 +2234,7 @@ PyObject_GC_Del(void *op) gc_list_remove(g); } PyThreadState *tstate = _PyThreadState_GET(); - GCState *gcstate = &tstate->interp->runtime->gc; + GCState *gcstate = &tstate->interp->gc; if (gcstate->generations[0].count > 0) { gcstate->generations[0].count--; } diff --git a/Objects/object.c b/Objects/object.c index 3e612825c2777..6fc114621c1d1 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2131,11 +2131,14 @@ Py_ReprLeave(PyObject *obj) void _PyTrash_deposit_object(PyObject *op) { + PyThreadState *tstate = _PyThreadState_GET(); + struct _gc_runtime_state *gcstate = &tstate->interp->gc; + _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); _PyObject_ASSERT(op, op->ob_refcnt == 0); - _PyGCHead_SET_PREV(_Py_AS_GC(op), _PyRuntime.gc.trash_delete_later); - _PyRuntime.gc.trash_delete_later = op; + _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later); + gcstate->trash_delete_later = op; } /* The equivalent API, using per-thread state recursion info */ @@ -2156,11 +2159,14 @@ _PyTrash_thread_deposit_object(PyObject *op) void _PyTrash_destroy_chain(void) { - while (_PyRuntime.gc.trash_delete_later) { - PyObject *op = _PyRuntime.gc.trash_delete_later; + PyThreadState *tstate = _PyThreadState_GET(); + struct _gc_runtime_state *gcstate = &tstate->interp->gc; + + while (gcstate->trash_delete_later) { + PyObject *op = gcstate->trash_delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; - _PyRuntime.gc.trash_delete_later = + gcstate->trash_delete_later = (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); /* Call the deallocator directly. This used to try to @@ -2170,9 +2176,9 @@ _PyTrash_destroy_chain(void) * up distorting allocation statistics. */ _PyObject_ASSERT(op, op->ob_refcnt == 0); - ++_PyRuntime.gc.trash_delete_nesting; + ++gcstate->trash_delete_nesting; (*dealloc)(op); - --_PyRuntime.gc.trash_delete_nesting; + --gcstate->trash_delete_nesting; } } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 41b9596b60d01..2149dbf569d6b 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1219,8 +1219,9 @@ finalize_interp_clear(PyThreadState *tstate, int is_main_interp) PyGrammar_RemoveAccelerators(&_PyParser_Grammar); _PyExc_Fini(); - _PyGC_Fini(tstate); } + + _PyGC_Fini(tstate); } diff --git a/Python/pystate.c b/Python/pystate.c index 93f0ce798888d..2fc563bf5836d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -58,7 +58,6 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) runtime->open_code_userdata = open_code_userdata; runtime->audit_hook_head = audit_hook_head; - _PyGC_InitializeRuntime(&runtime->gc); _PyEval_Initialize(&runtime->ceval); PyPreConfig_InitPythonConfig(&runtime->preconfig); @@ -208,6 +207,7 @@ PyInterpreterState_New(void) _PyRuntimeState *runtime = &_PyRuntime; interp->runtime = runtime; + _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); interp->eval_frame = _PyEval_EvalFrameDefault; From webhook-mailer at python.org Wed Nov 20 06:59:18 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 11:59:18 -0000 Subject: [Python-checkins] bpo-37340: Remove PyMethod_ClearFreeList() and PyCFunction_ClearFreeList() (GH-17284) Message-ID: https://github.com/python/cpython/commit/4dedd0f0ddc5a983a57bf0105eb34f948a91d2c4 commit: 4dedd0f0ddc5a983a57bf0105eb34f948a91d2c4 branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T12:59:12+01:00 summary: bpo-37340: Remove PyMethod_ClearFreeList() and PyCFunction_ClearFreeList() (GH-17284) Remove PyMethod_ClearFreeList() and PyCFunction_ClearFreeList() functions: the free lists of bound method objects have been removed. Remove also _PyMethod_Fini() and _PyCFunction_Fini() functions. files: A Misc/NEWS.d/next/C API/2019-11-20-11-08-06.bpo-37340.JBQJMS.rst M Doc/whatsnew/3.9.rst M Include/classobject.h M Include/internal/pycore_pylifecycle.h M Include/methodobject.h M Modules/gcmodule.c M Objects/classobject.c M Objects/methodobject.c M Python/pylifecycle.c diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 542a031960013..281173edb895b 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -217,6 +217,7 @@ Build and C API Changes ``PyThreadState.recursion_depth`` field. Remove ``_Py_CheckRecursionLimit`` from the stable ABI. (Contributed by Victor Stinner in :issue:`38644`.) + * Add a new public :c:func:`PyObject_CallNoArgs` function to the C API, which calls a callable Python object without any arguments. It is the most efficient way to call a callable Python object without any argument. @@ -230,6 +231,10 @@ Build and C API Changes ``pyfpe.h`` from ``Py_LIMITED_API`` (stable API). (Contributed by Victor Stinner in :issue:`38835`.) +* Remove ``PyMethod_ClearFreeList()`` and ``PyCFunction_ClearFreeList()`` + functions: the free lists of bound method objects have been removed. + (Contributed by Inada Naoki and Victor Stinner in :issue:`37340`.) + Deprecated ========== diff --git a/Include/classobject.h b/Include/classobject.h index c83303c390055..840431a127691 100644 --- a/Include/classobject.h +++ b/Include/classobject.h @@ -33,8 +33,6 @@ PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); #define PyMethod_GET_SELF(meth) \ (((PyMethodObject *)meth) -> im_self) -PyAPI_FUNC(int) PyMethod_ClearFreeList(void); - typedef struct { PyObject_HEAD PyObject *func; diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index b8d5e361b3c73..c837bcdbc03cc 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -59,9 +59,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate); /* Various internal finalizers */ -extern void _PyMethod_Fini(void); extern void _PyFrame_Fini(void); -extern void _PyCFunction_Fini(void); extern void _PyDict_Fini(void); extern void _PyTuple_Fini(void); extern void _PyList_Fini(void); diff --git a/Include/methodobject.h b/Include/methodobject.h index 3bccf5a3f60d3..a15d05f89917e 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -97,8 +97,6 @@ typedef struct { } PyCFunctionObject; #endif -PyAPI_FUNC(int) PyCFunction_ClearFreeList(void); - #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/C API/2019-11-20-11-08-06.bpo-37340.JBQJMS.rst b/Misc/NEWS.d/next/C API/2019-11-20-11-08-06.bpo-37340.JBQJMS.rst new file mode 100644 index 0000000000000..8ffa4eb12bd4e --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-20-11-08-06.bpo-37340.JBQJMS.rst @@ -0,0 +1,2 @@ +Remove ``PyMethod_ClearFreeList()`` and ``PyCFunction_ClearFreeList()`` +functions: the free lists of bound method objects have been removed. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 967bbe9c0d45d..d232179a11ce4 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1029,9 +1029,7 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, static void clear_freelists(void) { - (void)PyMethod_ClearFreeList(); (void)PyFrame_ClearFreeList(); - (void)PyCFunction_ClearFreeList(); (void)PyTuple_ClearFreeList(); (void)PyUnicode_ClearFreeList(); (void)PyFloat_ClearFreeList(); diff --git a/Objects/classobject.c b/Objects/classobject.c index d3fc726415406..db53f04862cd6 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -371,20 +371,6 @@ PyTypeObject PyMethod_Type = { method_new, /* tp_new */ }; -/* Clear out the free list */ - -int -PyMethod_ClearFreeList(void) -{ - return 0; -} - -void -_PyMethod_Fini(void) -{ - (void)PyMethod_ClearFreeList(); -} - /* ------------------------------------------------------------------------ * instance method */ diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 8f752c610ce4b..6a37238d86d8d 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -313,21 +313,6 @@ PyTypeObject PyCFunction_Type = { 0, /* tp_dict */ }; -/* Clear out the free list */ - -int -PyCFunction_ClearFreeList(void) -{ - return 0; -} - -void -_PyCFunction_Fini(void) -{ - (void)PyCFunction_ClearFreeList(); -} - - /* Vectorcall functions for each of the PyCFunction calling conventions, * except for METH_VARARGS (possibly combined with METH_KEYWORDS) which * doesn't use vectorcall. diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 2149dbf569d6b..44a4b18590b4b 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1173,9 +1173,7 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) { if (is_main_interp) { /* Sundry finalizers */ - _PyMethod_Fini(); _PyFrame_Fini(); - _PyCFunction_Fini(); _PyTuple_Fini(); _PyList_Fini(); _PySet_Fini(); From webhook-mailer at python.org Wed Nov 20 08:29:33 2019 From: webhook-mailer at python.org (Tal Einat) Date: Wed, 20 Nov 2019 13:29:33 -0000 Subject: [Python-checkins] bpo-38821: Fix crash in argparse when using gettext (GH-17192) Message-ID: https://github.com/python/cpython/commit/be5c79e0338005d675a64ba6e5b137e850d556d1 commit: be5c79e0338005d675a64ba6e5b137e850d556d1 branch: master author: Federico Bond committer: Tal Einat date: 2019-11-20T15:29:29+02:00 summary: bpo-38821: Fix crash in argparse when using gettext (GH-17192) files: A Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst M Lib/argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 94e1b8ad0ed18..5a8eff2f4cc89 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2148,10 +2148,11 @@ def _match_argument(self, action, arg_strings_pattern): OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } - default = ngettext('expected %s argument', + msg = nargs_errors.get(action.nargs) + if msg is None: + msg = ngettext('expected %s argument', 'expected %s arguments', action.nargs) % action.nargs - msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) # return the number of arguments matched diff --git a/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst new file mode 100644 index 0000000000000..2e7a22f661ac6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst @@ -0,0 +1 @@ +Fix unhandled exceptions in :mod:`argparse` when internationalizing error messages for arguments with ``nargs`` set to special (non-integer) values. Patch by Federico Bond. From webhook-mailer at python.org Wed Nov 20 08:48:25 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 13:48:25 -0000 Subject: [Python-checkins] bpo-38821: Fix crash in argparse when using gettext (GH-17192) Message-ID: https://github.com/python/cpython/commit/ecb2afc1bc1c2f3f9f99b09dd866100c3c7dcab7 commit: ecb2afc1bc1c2f3f9f99b09dd866100c3c7dcab7 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T05:48:20-08:00 summary: bpo-38821: Fix crash in argparse when using gettext (GH-17192) (cherry picked from commit be5c79e0338005d675a64ba6e5b137e850d556d1) Co-authored-by: Federico Bond files: A Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst M Lib/argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 24af355b74413..ac424f4914516 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2080,10 +2080,11 @@ def _match_argument(self, action, arg_strings_pattern): OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } - default = ngettext('expected %s argument', + msg = nargs_errors.get(action.nargs) + if msg is None: + msg = ngettext('expected %s argument', 'expected %s arguments', action.nargs) % action.nargs - msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) # return the number of arguments matched diff --git a/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst new file mode 100644 index 0000000000000..2e7a22f661ac6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst @@ -0,0 +1 @@ +Fix unhandled exceptions in :mod:`argparse` when internationalizing error messages for arguments with ``nargs`` set to special (non-integer) values. Patch by Federico Bond. From webhook-mailer at python.org Wed Nov 20 08:48:30 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 13:48:30 -0000 Subject: [Python-checkins] bpo-38821: Fix crash in argparse when using gettext (GH-17192) Message-ID: https://github.com/python/cpython/commit/836f137f7ae0799de937e5281cb1da2bfdb8a69d commit: 836f137f7ae0799de937e5281cb1da2bfdb8a69d branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T05:48:25-08:00 summary: bpo-38821: Fix crash in argparse when using gettext (GH-17192) (cherry picked from commit be5c79e0338005d675a64ba6e5b137e850d556d1) Co-authored-by: Federico Bond files: A Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst M Lib/argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index e590225c8eb8d..fd61bc78c2c3d 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2093,10 +2093,11 @@ def _match_argument(self, action, arg_strings_pattern): OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } - default = ngettext('expected %s argument', + msg = nargs_errors.get(action.nargs) + if msg is None: + msg = ngettext('expected %s argument', 'expected %s arguments', action.nargs) % action.nargs - msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) # return the number of arguments matched diff --git a/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst new file mode 100644 index 0000000000000..2e7a22f661ac6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-16-23-26-25.bpo-38821.-albNN.rst @@ -0,0 +1 @@ +Fix unhandled exceptions in :mod:`argparse` when internationalizing error messages for arguments with ``nargs`` set to special (non-integer) values. Patch by Federico Bond. From webhook-mailer at python.org Wed Nov 20 11:21:33 2019 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 20 Nov 2019 16:21:33 -0000 Subject: [Python-checkins] Update information about publishing a new version to the Microsoft Store (GH-17262) Message-ID: https://github.com/python/cpython/commit/db7925a1cac361ad8c94123a38b00b70f306c48d commit: db7925a1cac361ad8c94123a38b00b70f306c48d branch: master author: Steve Dower committer: GitHub date: 2019-11-20T08:21:14-08:00 summary: Update information about publishing a new version to the Microsoft Store (GH-17262) files: M PC/store_info.txt diff --git a/PC/store_info.txt b/PC/store_info.txt index 89f36998370fc..8c20412a5f071 100644 --- a/PC/store_info.txt +++ b/PC/store_info.txt @@ -60,9 +60,19 @@ https://partner.microsoft.com/dashboard. We keep it here for convenience and to allow it to be updated via pull requests. +When submitting a new app, the HeadlessAppBypass waiver will be needed. +To request this, send an email to PartnerOps at microsoft.com with the app +ID (12 character token available from the dashboard). The waiver needs +to be applied *before* uploading the package (as of November 2019). + +Ensure that the new app is named "Python.3.X", where X is the minor +version of the release. If the name provided initially does not match +the name used when building the package, the upload will fail. The +display name shown to users can be set later. + ## Title -Python 3.8 +Python 3.9 ## Short Title @@ -78,7 +88,7 @@ The Python interpreter is easily extended with new functions and data types impl ## ShortDescription -The Python 3.8 interpreter and runtime. +The Python 3.9 interpreter and runtime. ## Copyright Trademark Information @@ -86,38 +96,38 @@ The Python 3.8 interpreter and runtime. ## Additional License Terms -Visit https://docs.python.org/3.8/license.html for latest license terms. +Visit https://docs.python.org/3.9/license.html for latest license terms. -PSF LICENSE AGREEMENT FOR PYTHON 3.8 +PSF LICENSE AGREEMENT FOR PYTHON 3.9 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using Python - 3.8 software in source or binary form and its associated documentation. + 3.9 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, - distribute, and otherwise use Python 3.8 alone or in any derivative + distribute, and otherwise use Python 3.9 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright ? 2001-2018 Python Software Foundation; All Rights - Reserved" are retained in Python 3.8 alone or in any derivative version + Reserved" are retained in Python 3.9 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or - incorporates Python 3.8 or any part thereof, and wants to make the + incorporates Python 3.9 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python - 3.8. + 3.9. -4. PSF is making Python 3.8 available to Licensee on an "AS IS" basis. +4. PSF is making Python 3.9 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE - USE OF PYTHON 3.8 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + USE OF PYTHON 3.9 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.8 +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.9 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF - MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.8, OR ANY DERIVATIVE + MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.9, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of @@ -129,7 +139,7 @@ PSF LICENSE AGREEMENT FOR PYTHON 3.8 trademark sense to endorse or promote products or services of Licensee, or any third party. -8. By copying, installing or otherwise using Python 3.8, Licensee agrees +8. By copying, installing or otherwise using Python 3.9, Licensee agrees to be bound by the terms and conditions of this License Agreement. ## Features From webhook-mailer at python.org Wed Nov 20 11:34:44 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 16:34:44 -0000 Subject: [Python-checkins] bpo-38858: Add _Py_IsMainInterpreter(tstate) (GH-17293) Message-ID: https://github.com/python/cpython/commit/fff7bbfdb6b7c143b73b6b4b6b40e828c101110c commit: fff7bbfdb6b7c143b73b6b4b6b40e828c101110c branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T17:34:39+01:00 summary: bpo-38858: Add _Py_IsMainInterpreter(tstate) (GH-17293) files: M Include/internal/pycore_pystate.h M Modules/_threadmodule.c M Python/pystate.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 0c3c1e3df34de..936e9cbc65f7a 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -269,6 +269,8 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); #define _Py_CURRENTLY_FINALIZING(runtime, tstate) \ (runtime->finalizing == tstate) +PyAPI_FUNC(int) _Py_IsMainInterpreter(PyThreadState* tstate); + /* Variable and macro for in-line access to current thread and interpreter state */ diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index befd213bfebaa..4a651cea6c7ff 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1466,9 +1466,9 @@ static PyObject * _thread__is_main_interpreter_impl(PyObject *module) /*[clinic end generated code: output=7dd82e1728339adc input=cc1eb00fd4598915]*/ { - _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return PyBool_FromLong(interp == runtime->interpreters.main); + PyThreadState *tstate = _PyThreadState_GET(); + int is_main = _Py_IsMainInterpreter(tstate); + return PyBool_FromLong(is_main); } static PyMethodDef thread_methods[] = { diff --git a/Python/pystate.c b/Python/pystate.c index 2fc563bf5836d..0a6d035836e6e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -159,6 +159,12 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) #define HEAD_UNLOCK(runtime) \ PyThread_release_lock((runtime)->interpreters.mutex) +int +_Py_IsMainInterpreter(PyThreadState* tstate) +{ + return (tstate->interp == tstate->interp->runtime->interpreters.main); +} + /* Forward declaration */ static void _PyGILState_NoteThreadState( struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); From webhook-mailer at python.org Wed Nov 20 12:25:55 2019 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 20 Nov 2019 17:25:55 -0000 Subject: [Python-checkins] Add Python 3.8 to py based search in find_python.bat (GH-17188) Message-ID: https://github.com/python/cpython/commit/abce2d9bc6b990831d303f4cf9f2de8a6712a1fc commit: abce2d9bc6b990831d303f4cf9f2de8a6712a1fc branch: master author: Segev Finer committer: Steve Dower date: 2019-11-20T09:25:45-08:00 summary: Add Python 3.8 to py based search in find_python.bat (GH-17188) files: M PCbuild/find_python.bat diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index 40937a67c33ac..75413cdbfcf43 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -37,7 +37,7 @@ @if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 6)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found @rem If py.exe finds a recent enough version, use that one - at for %%p in (3.7 3.6) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found + at for %%p in (3.8 3.7 3.6) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found @if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%" @set _Py_NUGET=%NUGET% From webhook-mailer at python.org Wed Nov 20 12:30:53 2019 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 20 Nov 2019 17:30:53 -0000 Subject: [Python-checkins] bpo-33125: Add support for building and releasing Windows ARM64 packages (GH-16828) Message-ID: https://github.com/python/cpython/commit/de148f263fba75cd10d2cb010fe9c495cee4ec83 commit: de148f263fba75cd10d2cb010fe9c495cee4ec83 branch: master author: Steve Dower committer: GitHub date: 2019-11-20T09:30:47-08:00 summary: bpo-33125: Add support for building and releasing Windows ARM64 packages (GH-16828) Note that the support is not actually enabled yet, and so we won't be publishing these packages. However, for those who want to build it themselves (even by reusing the Azure Pipelines definition), it's now relatively easy to enable. files: A Misc/NEWS.d/next/Windows/2019-11-14-08-57-50.bpo-33125.EN5MWS.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .azure-pipelines/windows-release/build-steps.yml M .azure-pipelines/windows-release/layout-command.yml M .azure-pipelines/windows-release/msi-steps.yml M .azure-pipelines/windows-release/stage-build.yml M .azure-pipelines/windows-release/stage-layout-embed.yml M .azure-pipelines/windows-release/stage-layout-full.yml M .azure-pipelines/windows-release/stage-layout-msix.yml M .azure-pipelines/windows-release/stage-layout-nuget.yml M .azure-pipelines/windows-release/stage-pack-msix.yml M .azure-pipelines/windows-release/stage-pack-nuget.yml M .azure-pipelines/windows-release/stage-publish-nugetorg.yml M .azure-pipelines/windows-release/stage-publish-pythonorg.yml M .azure-pipelines/windows-release/stage-sign.yml M .azure-pipelines/windows-steps.yml M PC/layout/main.py M PC/layout/support/appxmanifest.py M PC/layout/support/constants.py M PC/layout/support/nuspec.py M PC/layout/support/props.py M PCbuild/build.bat M PCbuild/find_msbuild.bat M PCbuild/get_externals.bat M PCbuild/pcbuild.proj M PCbuild/prepare_libffi.bat M PCbuild/python_uwp.vcxproj M PCbuild/pythonw_uwp.vcxproj diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index fe10e45b67922..4c2f115cd9b60 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -145,7 +145,7 @@ jobs: buildOpt: '-p x64' testRunTitle: '$(Build.SourceBranchName)-win64' testRunPlatform: win64 - maxParallel: 2 + maxParallel: 4 steps: - template: ./windows-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 09209fc0c954d..73d4f55b86450 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -145,7 +145,10 @@ jobs: buildOpt: '-p x64' testRunTitle: '$(System.PullRequest.TargetBranch)-win64' testRunPlatform: win64 - maxParallel: 2 + winarm64: + arch: arm64 + buildOpt: '-p arm64' + maxParallel: 4 steps: - template: ./windows-steps.yml diff --git a/.azure-pipelines/windows-release/build-steps.yml b/.azure-pipelines/windows-release/build-steps.yml index d4563cd0d722c..e2b6683f46e3c 100644 --- a/.azure-pipelines/windows-release/build-steps.yml +++ b/.azure-pipelines/windows-release/build-steps.yml @@ -43,7 +43,7 @@ steps: - powershell: | $env:SigningCertificate = $null - .\python.bat PC\layout -vv -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default + python PC\layout -vv -b "$(Build.BinariesDirectory)\bin" -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default --arch $(Arch) makecat "${env:CAT}.cdf" del "${env:CAT}.cdf" if (-not (Test-Path "${env:CAT}.cat")) { @@ -52,6 +52,7 @@ steps: displayName: 'Generate catalog' env: CAT: $(Build.BinariesDirectory)\bin\$(Arch)\python + PYTHON_HEXVERSION: $(VersionHex) - task: PublishPipelineArtifact at 0 displayName: 'Publish binaries' diff --git a/.azure-pipelines/windows-release/layout-command.yml b/.azure-pipelines/windows-release/layout-command.yml index 2dcd6ed26ca3a..406ccd859faa6 100644 --- a/.azure-pipelines/windows-release/layout-command.yml +++ b/.azure-pipelines/windows-release/layout-command.yml @@ -1,12 +1,20 @@ steps: +- task: DownloadPipelineArtifact at 1 + displayName: 'Download artifact: bin_$(HostArch)' + condition: and(succeeded(), variables['HostArch']) + inputs: + artifactName: bin_$(HostArch) + targetPath: $(Build.BinariesDirectory)\bin_$(HostArch) + - powershell: > Write-Host ( '##vso[task.setvariable variable=LayoutCmd]& - "{0}\bin\python.exe" + "$(Python)" "{1}\PC\layout" -vv --source "{1}" --build "{0}\bin" + --arch "$(Name)" --temp "{0}\layout-temp" --include-cat "{0}\bin\python.cat" --doc-build "{0}\doc"' diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index f7bff162f8e02..a460eb1bac8fe 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -54,6 +54,7 @@ steps: - powershell: | copy $(Build.BinariesDirectory)\amd64\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force displayName: 'Copy signed files into sources' + condition: and(succeeded(), variables['SigningCertificate']) - script: | call Tools\msi\get_externals.bat diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index c98576ef9705c..60d72b282d1e5 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -16,14 +16,16 @@ jobs: env: BUILDDIR: $(Build.BinariesDirectory)\Doc - #- powershell: iwr "https://www.python.org/ftp/python/3.7.3/python373.chm" -OutFile "$(Build.BinariesDirectory)\python390a0.chm" - # displayName: 'Cheat at building CHM docs' - - script: Doc\make.bat htmlhelp displayName: 'Build CHM docs' env: BUILDDIR: $(Build.BinariesDirectory)\Doc + #- powershell: | + # mkdir -Force "$(Build.BinariesDirectory)\Doc\htmlhelp" + # iwr "https://www.python.org/ftp/python/3.8.0/python380.chm" -OutFile "$(Build.BinariesDirectory)\Doc\htmlhelp\python390a0.chm" + # displayName: 'Cheat at building CHM docs' + - task: CopyFiles at 2 displayName: 'Assemble artifact: Doc' inputs: @@ -65,6 +67,16 @@ jobs: Arch: amd64 Platform: x64 Configuration: Debug + arm64: + Name: arm64 + Arch: arm64 + Platform: ARM64 + Configuration: Release + arm64_d: + Name: arm64_d + Arch: arm64 + Platform: ARM64 + Configuration: Debug steps: - template: ./build-steps.yml diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml index 09857ff676b35..3306e1cbc49d9 100644 --- a/.azure-pipelines/windows-release/stage-layout-embed.yml +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -19,6 +19,11 @@ jobs: Name: amd64 Python: $(Build.BinariesDirectory)\bin\python.exe PYTHONHOME: $(Build.SourcesDirectory) + arm64: + Name: arm64 + HostArch: amd64 + Python: $(Build.BinariesDirectory)\bin_amd64\python.exe + PYTHONHOME: $(Build.SourcesDirectory) steps: - template: ./checkout.yml diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml index 12c347239013c..78bc1b3975e93 100644 --- a/.azure-pipelines/windows-release/stage-layout-full.yml +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -13,11 +13,18 @@ jobs: matrix: win32: Name: win32 - Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + Python: $(Build.BinariesDirectory)\bin\python.exe PYTHONHOME: $(Build.SourcesDirectory) + TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 amd64: Name: amd64 - Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + Python: $(Build.BinariesDirectory)\bin\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + arm64: + Name: arm64 + HostArch: amd64 + Python: $(Build.BinariesDirectory)\bin_amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) steps: @@ -43,13 +50,15 @@ jobs: - task: DownloadPipelineArtifact at 1 displayName: 'Download artifact: tcltk_lib_$(Name)' + condition: and(succeeded(), variables['TclLibrary']) inputs: artifactName: tcltk_lib_$(Name) targetPath: $(Build.BinariesDirectory)\tcltk_lib - powershell: | - copy $(Build.BinariesDirectory)\bin\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force + copy "$(Build.BinariesDirectory)\bin\Activate.ps1" Lib\venv\scripts\common\Activate.ps1 -Force displayName: 'Copy signed files into sources' + condition: and(succeeded(), variables['SigningCertificate']) - template: ./layout-command.yml @@ -57,7 +66,7 @@ jobs: $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\layout" --preset-default displayName: 'Generate full layout' env: - TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + TCL_LIBRARY: $(TclLibrary) - task: PublishPipelineArtifact at 0 displayName: 'Publish Artifact: layout_full_$(Name)' diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml index ba86392f3ec69..60a5c9ea5435c 100644 --- a/.azure-pipelines/windows-release/stage-layout-msix.yml +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -12,11 +12,18 @@ jobs: matrix: #win32: # Name: win32 - # Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + # Python: $(Build.BinariesDirectory)\bin\python.exe # PYTHONHOME: $(Build.SourcesDirectory) + # TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 amd64: Name: amd64 - Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + Python: $(Build.BinariesDirectory)\bin\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + arm64: + Name: arm64 + HostArch: amd64 + Python: $(Build.BinariesDirectory)\bin_amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) steps: @@ -36,13 +43,15 @@ jobs: - task: DownloadPipelineArtifact at 1 displayName: 'Download artifact: tcltk_lib_$(Name)' + condition: and(succeeded(), variables['TclLibrary']) inputs: artifactName: tcltk_lib_$(Name) targetPath: $(Build.BinariesDirectory)\tcltk_lib - powershell: | - copy $(Build.BinariesDirectory)\bin\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force + copy "$(Build.BinariesDirectory)\bin\Activate.ps1" Lib\venv\scripts\common\Activate.ps1 -Force displayName: 'Copy signed files into sources' + condition: and(succeeded(), variables['SigningCertificate']) - template: ./layout-command.yml @@ -51,7 +60,7 @@ jobs: $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx-store" --preset-appx --precompile displayName: 'Generate store APPX layout' env: - TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + TCL_LIBRARY: $(TclLibrary) - task: PublishPipelineArtifact at 0 displayName: 'Publish Artifact: layout_appxstore_$(Name)' @@ -79,7 +88,7 @@ jobs: $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx" --preset-appx --precompile --include-symbols --include-tests displayName: 'Generate sideloading APPX layout' env: - TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + TCL_LIBRARY: $(TclLibrary) - task: PublishPipelineArtifact at 0 displayName: 'Publish Artifact: layout_appx_$(Name)' diff --git a/.azure-pipelines/windows-release/stage-layout-nuget.yml b/.azure-pipelines/windows-release/stage-layout-nuget.yml index 7954c4547f50a..7e20f89530349 100644 --- a/.azure-pipelines/windows-release/stage-layout-nuget.yml +++ b/.azure-pipelines/windows-release/stage-layout-nuget.yml @@ -13,11 +13,16 @@ jobs: matrix: win32: Name: win32 - Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + Python: $(Build.BinariesDirectory)\bin\python.exe PYTHONHOME: $(Build.SourcesDirectory) amd64: Name: amd64 - Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + Python: $(Build.BinariesDirectory)\bin\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + arm64: + Name: arm64 + HostArch: amd64 + Python: $(Build.BinariesDirectory)\bin_amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) steps: @@ -32,14 +37,13 @@ jobs: - powershell: | copy $(Build.BinariesDirectory)\bin\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force displayName: 'Copy signed files into sources' + condition: and(succeeded(), variables['SigningCertificate']) - template: ./layout-command.yml - powershell: | $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\nuget" --preset-nuget displayName: 'Generate nuget layout' - env: - TCL_LIBRARY: $(Build.BinariesDirectory)\bin_$(Name)\tcl\tcl8 - task: PublishPipelineArtifact at 0 displayName: 'Publish Artifact: layout_nuget_$(Name)' diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml index eebc63fb8809b..f17ba9628e21b 100644 --- a/.azure-pipelines/windows-release/stage-pack-msix.yml +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -20,6 +20,16 @@ jobs: Artifact: appxstore Suffix: -store Upload: true + arm64: + Name: arm64 + Artifact: appx + Suffix: + ShouldSign: true + arm64_store: + Name: arm64 + Artifact: appxstore + Suffix: -store + Upload: true steps: - template: ./checkout.yml diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml index f59bbe9b39a8d..34619fc5fdc31 100644 --- a/.azure-pipelines/windows-release/stage-pack-nuget.yml +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -15,6 +15,8 @@ jobs: Name: amd64 win32: Name: win32 + arm64: + Name: arm64 steps: - checkout: none diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml index 570cdb3ec57f0..5aba048cd72a6 100644 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -31,6 +31,11 @@ jobs: buildVersionToDownload: specific buildId: $(BuildToPublish) + - powershell: gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del + displayName: 'Prevent publishing ARM/ARM64 packages' + workingDirectory: '$(Build.BinariesDirectory)\nuget' + condition: and(succeeded(), not(variables['PublishArmPackages'])) + - task: NuGetCommand at 2 displayName: Push packages condition: and(succeeded(), eq(variables['SigningCertificate'], variables['__RealSigningCertificate'])) diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index 2dd354a8c276f..6c61e9ac3bdbb 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -39,6 +39,10 @@ jobs: artifactName: embed downloadPath: $(Build.BinariesDirectory) + - powershell: gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del + displayName: 'Prevent publishing ARM/ARM64 packages' + workingDirectory: '$(Build.BinariesDirectory)\embed' + condition: and(succeeded(), not(variables['PublishArmPackages'])) - task: DownloadPipelineArtifact at 1 displayName: 'Download artifact from $(BuildToPublish): Doc' diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml index 2307c6c9c8f97..a0adc0581229d 100644 --- a/.azure-pipelines/windows-release/stage-sign.yml +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -19,6 +19,8 @@ jobs: Name: win32 amd64: Name: amd64 + arm64: + Name: arm64 steps: - template: ./checkout.yml diff --git a/.azure-pipelines/windows-steps.yml b/.azure-pipelines/windows-steps.yml index 794a23a5d77e8..f502c40637c31 100644 --- a/.azure-pipelines/windows-steps.yml +++ b/.azure-pipelines/windows-steps.yml @@ -19,9 +19,11 @@ steps: - script: python.bat -m test.pythoninfo displayName: 'Display build info' + condition: and(succeeded(), variables['testRunPlatform']) - script: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results.xml" --tempdir="$(Build.BinariesDirectory)\test" displayName: 'Tests' + condition: and(succeeded(), variables['testRunPlatform']) env: PREFIX: $(Py_OutDir)\$(arch) @@ -32,4 +34,4 @@ steps: mergeTestResults: true testRunTitle: $(testRunTitle) platform: $(testRunPlatform) - condition: succeededOrFailed() + condition: and(succeededOrFailed(), variables['testRunPlatform']) diff --git a/Misc/NEWS.d/next/Windows/2019-11-14-08-57-50.bpo-33125.EN5MWS.rst b/Misc/NEWS.d/next/Windows/2019-11-14-08-57-50.bpo-33125.EN5MWS.rst new file mode 100644 index 0000000000000..0bc98c1a2fae7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-11-14-08-57-50.bpo-33125.EN5MWS.rst @@ -0,0 +1 @@ +Add support for building and releasing Windows ARM64 packages. diff --git a/PC/layout/main.py b/PC/layout/main.py index 3ca49d08e8f98..305cb517d0f71 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -285,14 +285,13 @@ def _compile_one_py(src, dest, name, optimize, checked=True): log_warning("Failed to compile {}", src) return None + # name argument added to address bpo-37641 def _py_temp_compile(src, name, ns, dest_dir=None, checked=True): if not ns.precompile or src not in PY_FILES or src.parent in DATA_DIRS: return None dest = (dest_dir or ns.temp) / (src.stem + ".pyc") - return _compile_one_py( - src, dest, name, optimize=2, checked=checked - ) + return _compile_one_py(src, dest, name, optimize=2, checked=checked) def _write_to_zip(zf, dest, src, ns, checked=True): @@ -496,6 +495,13 @@ def main(): parser.add_argument( "-b", "--build", metavar="dir", help="Specify the build directory", type=Path ) + parser.add_argument( + "--arch", + metavar="architecture", + help="Specify the target architecture", + type=str, + default=None, + ) parser.add_argument( "--doc-build", metavar="dir", @@ -587,6 +593,8 @@ def main(): ns.doc_build = (Path.cwd() / ns.doc_build).resolve() if ns.include_cat and not ns.include_cat.is_absolute(): ns.include_cat = (Path.cwd() / ns.include_cat).resolve() + if not ns.arch: + ns.arch = "amd64" if sys.maxsize > 2 ** 32 else "win32" if ns.copy and not ns.copy.is_absolute(): ns.copy = (Path.cwd() / ns.copy).resolve() @@ -602,6 +610,7 @@ def main(): Source: {ns.source} Build: {ns.build} Temp: {ns.temp} +Arch: {ns.arch} Copy to: {ns.copy} Zip to: {ns.zip} @@ -609,6 +618,15 @@ def main(): ns=ns, ) + if ns.arch not in ("win32", "amd64", "arm32", "arm64"): + log_error("--arch is not a valid value (win32, amd64, arm32, arm64)") + return 4 + if ns.arch in ("arm32", "arm64"): + for n in ("include_idle", "include_tcltk"): + if getattr(ns, n): + log_warning(f"Disabling --{n.replace('_', '-')} on unsupported platform") + setattr(ns, n, False) + if ns.include_idle and not ns.include_tcltk: log_warning("Assuming --include-tcltk to support --include-idle") ns.include_tcltk = True diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index de5813a2536ae..9e008f793cf55 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -28,7 +28,14 @@ ), DisplayName="Python {}".format(VER_DOT), Description="The Python {} runtime and console.".format(VER_DOT), - ProcessorArchitecture="x64" if IS_X64 else "x86", +) + +APPX_PLATFORM_DATA = dict( + _keys=("ProcessorArchitecture",), + win32=("x86",), + amd64=("x64",), + arm32=("arm",), + arm64=("arm64",), ) PYTHON_VE_DATA = dict( @@ -65,7 +72,7 @@ BackgroundColor="transparent", ) -PY_PNG = '_resources/py.png' +PY_PNG = "_resources/py.png" APPXMANIFEST_NS = { "": "http://schemas.microsoft.com/appx/manifest/foundation/windows10", @@ -147,18 +154,22 @@ SCCD_FILENAME = "PC/classicAppCompat.sccd" +SPECIAL_LOOKUP = object() + REGISTRY = { "HKCU\\Software\\Python\\PythonCore": { VER_DOT: { "DisplayName": APPX_DATA["DisplayName"], "SupportUrl": "https://www.python.org/", - "SysArchitecture": "64bit" if IS_X64 else "32bit", + "SysArchitecture": SPECIAL_LOOKUP, "SysVersion": VER_DOT, "Version": "{}.{}.{}".format(VER_MAJOR, VER_MINOR, VER_MICRO), "InstallPath": { "": "[{AppVPackageRoot}]", "ExecutablePath": "[{{AppVPackageRoot}}]\\python{}.exe".format(VER_DOT), - "WindowedExecutablePath": "[{{AppVPackageRoot}}]\\pythonw{}.exe".format(VER_DOT), + "WindowedExecutablePath": "[{{AppVPackageRoot}}]\\pythonw{}.exe".format( + VER_DOT + ), }, "Help": { "Main Python Documentation": { @@ -338,6 +349,16 @@ def _get_registry_entries(ns, root="", d=None): if len(fullkey.parts) > 1: yield str(fullkey), None, None yield from _get_registry_entries(ns, fullkey, value) + elif value is SPECIAL_LOOKUP: + if key == "SysArchitecture": + return { + "win32": "32bit", + "amd64": "64bit", + "arm32": "32bit", + "arm64": "64bit", + }[ns.arch] + else: + raise ValueError(f"Key '{key}' unhandled for special lookup") elif len(r.parts) > 1: yield str(r), key, value @@ -376,14 +397,18 @@ def get_appxmanifest(ns): NS = APPXMANIFEST_NS QN = ET.QName + data = dict(APPX_DATA) + for k, v in zip(APPX_PLATFORM_DATA["_keys"], APPX_PLATFORM_DATA[ns.arch]): + data[k] = v + node = xml.find("m:Identity", NS) for k in node.keys(): - value = APPX_DATA.get(k) + value = data.get(k) if value: node.set(k, value) for node in xml.find("m:Properties", NS): - value = APPX_DATA.get(node.tag.rpartition("}")[2]) + value = data.get(node.tag.rpartition("}")[2]) if value: node.text = value @@ -405,7 +430,7 @@ def get_appxmanifest(ns): ["python", "python{}".format(VER_MAJOR), "python{}".format(VER_DOT)], PYTHON_VE_DATA, "console", - ("python.file", [".py"], '"%1"', 'Python File', PY_PNG), + ("python.file", [".py"], '"%1"', "Python File", PY_PNG), ) add_application( @@ -416,7 +441,7 @@ def get_appxmanifest(ns): ["pythonw", "pythonw{}".format(VER_MAJOR), "pythonw{}".format(VER_DOT)], PYTHONW_VE_DATA, "windows", - ("python.windowedfile", [".pyw"], '"%1"', 'Python File (no console)', PY_PNG), + ("python.windowedfile", [".pyw"], '"%1"', "Python File (no console)", PY_PNG), ) if ns.include_pip and ns.include_launchers: @@ -428,7 +453,7 @@ def get_appxmanifest(ns): ["pip", "pip{}".format(VER_MAJOR), "pip{}".format(VER_DOT)], PIP_VE_DATA, "console", - ("python.wheel", [".whl"], 'install "%1"', 'Python Wheel'), + ("python.wheel", [".whl"], 'install "%1"', "Python Wheel"), ) if ns.include_idle and ns.include_launchers: diff --git a/PC/layout/support/constants.py b/PC/layout/support/constants.py index d76fa3bbf3b47..a8647631e9b4c 100644 --- a/PC/layout/support/constants.py +++ b/PC/layout/support/constants.py @@ -5,15 +5,31 @@ __author__ = "Steve Dower " __version__ = "3.8" +import os +import re import struct import sys -VER_MAJOR, VER_MINOR, VER_MICRO, VER_FIELD4 = struct.pack(">i", sys.hexversion) + +def _unpack_hexversion(): + try: + hexversion = int(os.getenv("PYTHON_HEXVERSION"), 16) + except (TypeError, ValueError): + hexversion = sys.hexversion + return struct.pack(">i", sys.hexversion) + + +def _get_suffix(field4): + name = {0xA0: "a", 0xB0: "b", 0xC0: "c"}.get(field4 & 0xF0, "") + if name: + serial = field4 & 0x0F + return f"{name}{serial}" + return "" + + +VER_MAJOR, VER_MINOR, VER_MICRO, VER_FIELD4 = _unpack_hexversion() +VER_SUFFIX = _get_suffix(VER_FIELD4) VER_FIELD3 = VER_MICRO << 8 | VER_FIELD4 -VER_NAME = {"alpha": "a", "beta": "b", "candidate": "rc"}.get( - sys.version_info.releaselevel, "" -) -VER_SERIAL = sys.version_info.serial if VER_NAME else "" VER_DOT = "{}.{}".format(VER_MAJOR, VER_MINOR) PYTHON_DLL_NAME = "python{}{}.dll".format(VER_MAJOR, VER_MINOR) @@ -21,8 +37,6 @@ PYTHON_ZIP_NAME = "python{}{}.zip".format(VER_MAJOR, VER_MINOR) PYTHON_PTH_NAME = "python{}{}._pth".format(VER_MAJOR, VER_MINOR) -PYTHON_CHM_NAME = "python{}{}{}{}{}.chm".format( - VER_MAJOR, VER_MINOR, VER_MICRO, VER_NAME, VER_SERIAL +PYTHON_CHM_NAME = "python{}{}{}{}.chm".format( + VER_MAJOR, VER_MINOR, VER_MICRO, VER_SUFFIX ) - -IS_X64 = sys.maxsize > 2 ** 32 diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py index ba26ff337e91e..b85095c555fe0 100644 --- a/PC/layout/support/nuspec.py +++ b/PC/layout/support/nuspec.py @@ -13,25 +13,21 @@ NUSPEC_DATA = { "PYTHON_TAG": VER_DOT, "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), - "PYTHON_BITNESS": "64-bit" if IS_X64 else "32-bit", - "PACKAGENAME": os.getenv("PYTHON_NUSPEC_PACKAGENAME"), - "PACKAGETITLE": os.getenv("PYTHON_NUSPEC_PACKAGETITLE"), "FILELIST": r' ', } -if not NUSPEC_DATA["PYTHON_VERSION"]: - if VER_NAME: - NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}-{}{}".format( - VER_DOT, VER_MICRO, VER_NAME, VER_SERIAL - ) - else: - NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}".format(VER_DOT, VER_MICRO) - -if not NUSPEC_DATA["PACKAGETITLE"]: - NUSPEC_DATA["PACKAGETITLE"] = "Python" if IS_X64 else "Python (32-bit)" +NUSPEC_PLATFORM_DATA = dict( + _keys=("PYTHON_BITNESS", "PACKAGENAME", "PACKAGETITLE"), + win32=("32-bit", "pythonx86", "Python (32-bit)"), + amd64=("64-bit", "python", "Python"), + arm32=("ARM", "pythonarm", "Python (ARM)"), + arm64=("ARM64", "pythonarm64", "Python (ARM64)"), +) -if not NUSPEC_DATA["PACKAGENAME"]: - NUSPEC_DATA["PACKAGENAME"] = "python" if IS_X64 else "pythonx86" +if not NUSPEC_DATA["PYTHON_VERSION"]: + NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}{}{}".format( + VER_DOT, VER_MICRO, "-" if VER_SUFFIX else "", VER_SUFFIX + ) FILELIST_WITH_PROPS = r""" """ @@ -56,11 +52,21 @@ """ +def _get_nuspec_data_overrides(ns): + for k, v in zip(NUSPEC_PLATFORM_DATA["_keys"], NUSPEC_PLATFORM_DATA[ns.arch]): + ev = os.getenv("PYTHON_NUSPEC_" + k) + if ev: + yield k, ev + yield k, v + + def get_nuspec_layout(ns): if ns.include_all or ns.include_nuspec: - data = NUSPEC_DATA + data = dict(NUSPEC_DATA) + for k, v in _get_nuspec_data_overrides(ns): + if not data.get(k): + data[k] = v if ns.include_all or ns.include_props: - data = dict(data) data["FILELIST"] = FILELIST_WITH_PROPS nuspec = NUSPEC_TEMPLATE.format_map(data) yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) diff --git a/PC/layout/support/props.py b/PC/layout/support/props.py index 4d3b06195f6ed..b1560b5244762 100644 --- a/PC/layout/support/props.py +++ b/PC/layout/support/props.py @@ -18,15 +18,9 @@ } if not PROPS_DATA["PYTHON_VERSION"]: - if VER_NAME: - PROPS_DATA["PYTHON_VERSION"] = "{}.{}-{}{}".format( - VER_DOT, VER_MICRO, VER_NAME, VER_SERIAL - ) - else: - PROPS_DATA["PYTHON_VERSION"] = "{}.{}".format(VER_DOT, VER_MICRO) - -if not PROPS_DATA["PYTHON_PLATFORM"]: - PROPS_DATA["PYTHON_PLATFORM"] = "x64" if IS_X64 else "Win32" + PROPS_DATA["PYTHON_VERSION"] = "{}.{}{}{}".format( + VER_DOT, VER_MICRO, "-" if VER_SUFFIX else "", VER_SUFFIX + ) PROPS_DATA["PYTHON_TARGET"] = "_GetPythonRuntimeFilesDependsOn{}{}_{}".format( VER_MAJOR, VER_MINOR, PROPS_DATA["PYTHON_PLATFORM"] @@ -94,5 +88,13 @@ def get_props_layout(ns): if ns.include_all or ns.include_props: # TODO: Filter contents of props file according to included/excluded items - props = PROPS_TEMPLATE.format_map(PROPS_DATA) + d = dict(PROPS_DATA) + if not d.get("PYTHON_PLATFORM"): + d["PYTHON_PLATFORM"] = { + "win32": "Win32", + "amd64": "X64", + "arm32": "ARM", + "arm64": "ARM64", + }[ns.arch] + props = PROPS_TEMPLATE.format_map(d) yield "python.props", ("python.props", props.encode("utf-8")) diff --git a/PCbuild/build.bat b/PCbuild/build.bat index bce599329e73a..623409c24ec04 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -57,7 +57,7 @@ set conf=Release set target=Build set dir=%~dp0 set parallel=/m -set verbose=/nologo /v:m +set verbose=/nologo /v:m /clp:summary set kill= set do_pgo= set pgo_job=-m test --pgo diff --git a/PCbuild/find_msbuild.bat b/PCbuild/find_msbuild.bat index a2810f09c45e2..bc9d00c22c826 100644 --- a/PCbuild/find_msbuild.bat +++ b/PCbuild/find_msbuild.bat @@ -32,7 +32,7 @@ @rem VS 2017 and later provide vswhere.exe, which can be used @if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" goto :skip_vswhere @set _Py_MSBuild_Root= - at for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest') DO @(set _Py_MSBuild_Root=%%i\MSBuild) + at for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease') DO @(set _Py_MSBuild_Root=%%i\MSBuild) @if not defined _Py_MSBuild_Root goto :skip_vswhere @for %%j in (Current 15.0) DO @if exist "%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe" (set MSBUILD="%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe") @set _Py_MSBuild_Root= diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 100149e83c164..f6daf325ef537 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -52,7 +52,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.6 -if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0-rc0-r1 +if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1d set libraries=%libraries% sqlite-3.28.0.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index 35f173ff864ea..22a9eed18d42b 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -60,7 +60,7 @@ - + diff --git a/PCbuild/prepare_libffi.bat b/PCbuild/prepare_libffi.bat index c65a5f7010bd0..f41ba83379af9 100644 --- a/PCbuild/prepare_libffi.bat +++ b/PCbuild/prepare_libffi.bat @@ -93,7 +93,10 @@ echo LIBFFI_SOURCE: %LIBFFI_SOURCE% echo MSVCC : %MSVCC% echo. -if not exist Makefile.in (%SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)") +if not exist Makefile.in ( + %SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)" + if errorlevel 1 exit /B 1 +) if "%BUILD_X64%"=="1" call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin if "%BUILD_X86%"=="1" call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin @@ -158,11 +161,13 @@ echo ================================================================ echo Configure the build to generate fficonfig.h and ffi.h echo ================================================================ %SH% -lc "(cd $OLDPWD; ./configure CC='%MSVCC% %ASSEMBLER% %BUILD_PDB%' CXX='%MSVCC% %ASSEMBLER% %BUILD_PDB%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' %BUILD_NOOPT% NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)" +if errorlevel 1 exit /B %ERRORLEVEL% echo ================================================================ echo Building libffi echo ================================================================ %SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)" +if errorlevel 1 exit /B %ERRORLEVEL% REM Tests are not needed to produce artifacts if "%LIBFFI_TEST%" EQU "1" ( diff --git a/PCbuild/python_uwp.vcxproj b/PCbuild/python_uwp.vcxproj index 14e138cbed3e0..5ff120a0da331 100644 --- a/PCbuild/python_uwp.vcxproj +++ b/PCbuild/python_uwp.vcxproj @@ -1,6 +1,14 @@ ? + + Debug + ARM + + + Debug + ARM64 + Debug Win32 @@ -9,6 +17,14 @@ Debug x64 + + PGInstrument + ARM + + + PGInstrument + ARM64 + PGInstrument Win32 @@ -17,6 +33,14 @@ PGInstrument x64 + + PGUpdate + ARM + + + PGUpdate + ARM64 + PGUpdate Win32 @@ -25,6 +49,14 @@ PGUpdate x64 + + Release + ARM + + + Release + ARM64 + Release Win32 diff --git a/PCbuild/pythonw_uwp.vcxproj b/PCbuild/pythonw_uwp.vcxproj index e2c01710498ee..828d0d1ccac21 100644 --- a/PCbuild/pythonw_uwp.vcxproj +++ b/PCbuild/pythonw_uwp.vcxproj @@ -1,6 +1,14 @@ ? + + Debug + ARM + + + Debug + ARM64 + Debug Win32 @@ -9,6 +17,14 @@ Debug x64 + + PGInstrument + ARM + + + PGInstrument + ARM64 + PGInstrument Win32 @@ -17,6 +33,14 @@ PGInstrument x64 + + PGUpdate + ARM + + + PGUpdate + ARM64 + PGUpdate Win32 @@ -25,6 +49,14 @@ PGUpdate x64 + + Release + ARM + + + Release + ARM64 + Release Win32 From webhook-mailer at python.org Wed Nov 20 12:39:18 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Wed, 20 Nov 2019 17:39:18 -0000 Subject: [Python-checkins] bpo-38858: Fix Py_Finalize() when called from a subinterpreter (GH-17297) Message-ID: https://github.com/python/cpython/commit/b93f31fcd9f10b213c614d4944baf9ca2df2016c commit: b93f31fcd9f10b213c614d4944baf9ca2df2016c branch: master author: Victor Stinner committer: GitHub date: 2019-11-20T18:39:12+01:00 summary: bpo-38858: Fix Py_Finalize() when called from a subinterpreter (GH-17297) Use _Py_IsMainInterpreter() in Py_Initialize() and Py_Finalize() to detect if the current interpreter is the main interpreter or not. files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 44a4b18590b4b..7591f069b455d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -558,9 +558,10 @@ pycore_create_interpreter(_PyRuntimeState *runtime, static PyStatus -pycore_init_types(PyThreadState *tstate, int is_main_interp) +pycore_init_types(PyThreadState *tstate) { PyStatus status; + int is_main_interp = _Py_IsMainInterpreter(tstate); status = _PyGC_Init(tstate); if (_PyStatus_EXCEPTION(status)) { @@ -576,7 +577,9 @@ pycore_init_types(PyThreadState *tstate, int is_main_interp) if (!_PyLong_Init()) { return _PyStatus_ERR("can't init longs"); } + } + if (is_main_interp) { status = _PyUnicode_Init(); if (_PyStatus_EXCEPTION(status)) { return status; @@ -696,7 +699,7 @@ pyinit_config(_PyRuntimeState *runtime, config = &tstate->interp->config; *tstate_p = tstate; - status = pycore_init_types(tstate, 1); + status = pycore_init_types(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1179,6 +1182,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PySet_Fini(); _PyBytes_Fini(); _PyLong_Fini(); + } + + if (is_main_interp) { _PyFloat_Fini(); _PyDict_Fini(); _PySlice_Fini(); @@ -1200,8 +1206,10 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) static void -finalize_interp_clear(PyThreadState *tstate, int is_main_interp) +finalize_interp_clear(PyThreadState *tstate) { + int is_main_interp = _Py_IsMainInterpreter(tstate); + /* Clear interpreter state and all thread states */ PyInterpreterState_Clear(tstate->interp); @@ -1224,9 +1232,9 @@ finalize_interp_clear(PyThreadState *tstate, int is_main_interp) static void -finalize_interp_delete(PyThreadState *tstate, int is_main_interp) +finalize_interp_delete(PyThreadState *tstate) { - if (is_main_interp) { + if (_Py_IsMainInterpreter(tstate)) { /* Cleanup auto-thread-state */ _PyGILState_Fini(tstate); } @@ -1388,9 +1396,8 @@ Py_FinalizeEx(void) } #endif /* Py_TRACE_REFS */ - finalize_interp_clear(tstate, 1); - - finalize_interp_delete(tstate, 1); + finalize_interp_clear(tstate); + finalize_interp_delete(tstate); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. @@ -1482,7 +1489,7 @@ new_interpreter(PyThreadState **tstate_p) } config = &interp->config; - status = pycore_init_types(tstate, 0); + status = pycore_init_types(tstate); /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); @@ -1634,8 +1641,8 @@ Py_EndInterpreter(PyThreadState *tstate) } _PyImport_Cleanup(tstate); - finalize_interp_clear(tstate, 0); - finalize_interp_delete(tstate, 0); + finalize_interp_clear(tstate); + finalize_interp_delete(tstate); } /* Add the __main__ module */ From webhook-mailer at python.org Wed Nov 20 15:02:28 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 20:02:28 -0000 Subject: [Python-checkins] bpo-38841: Skip asyncio test_create_datagram_endpoint_existing_sock_unix (GH-17294) Message-ID: https://github.com/python/cpython/commit/559bad1a70ed50cc9caa7cb303b6ac1fe6a34af3 commit: 559bad1a70ed50cc9caa7cb303b6ac1fe6a34af3 branch: master author: xdegaye committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T12:02:07-08:00 summary: bpo-38841: Skip asyncio test_create_datagram_endpoint_existing_sock_unix (GH-17294) on platforms lacking a functional bind() for named unix domain sockets https://bugs.python.org/issue38841 Automerge-Triggered-By: @asvetlov files: A Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst M Lib/test/test_asyncio/test_base_events.py diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 66191d9d1c1ad..ca99d5c6c0ac8 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1700,7 +1700,7 @@ def test_create_datagram_endpoint_sock_unix(self): self.loop.run_until_complete(protocol.done) self.assertEqual('CLOSED', protocol.state) - @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + @support.skip_unless_bind_unix_socket def test_create_datagram_endpoint_existing_sock_unix(self): with test_utils.unix_socket_path() as path: sock = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM) diff --git a/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst b/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst new file mode 100644 index 0000000000000..1f4ae424bbcde --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst @@ -0,0 +1,2 @@ +Skip asyncio test_create_datagram_endpoint_existing_sock_unix on platforms +lacking a functional bind() for named unix domain sockets. From webhook-mailer at python.org Wed Nov 20 15:20:29 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 20 Nov 2019 20:20:29 -0000 Subject: [Python-checkins] bpo-38841: Skip asyncio test_create_datagram_endpoint_existing_sock_unix (GH-17294) Message-ID: https://github.com/python/cpython/commit/b762375ba28893be73f166576aecde44ad2f4001 commit: b762375ba28893be73f166576aecde44ad2f4001 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T12:20:25-08:00 summary: bpo-38841: Skip asyncio test_create_datagram_endpoint_existing_sock_unix (GH-17294) on platforms lacking a functional bind() for named unix domain sockets https://bugs.python.org/issue38841 Automerge-Triggered-By: @asvetlov (cherry picked from commit 559bad1a70ed50cc9caa7cb303b6ac1fe6a34af3) Co-authored-by: xdegaye files: A Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst M Lib/test/test_asyncio/test_base_events.py diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index ccdd3bae73367..92fdaf17e2011 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1694,7 +1694,7 @@ def test_create_datagram_endpoint_sock_unix(self): self.loop.run_until_complete(protocol.done) self.assertEqual('CLOSED', protocol.state) - @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + @support.skip_unless_bind_unix_socket def test_create_datagram_endpoint_existing_sock_unix(self): with test_utils.unix_socket_path() as path: sock = socket.socket(socket.AF_UNIX, type=socket.SOCK_DGRAM) diff --git a/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst b/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst new file mode 100644 index 0000000000000..1f4ae424bbcde --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-20-16-08-19.bpo-38841.5F5Lbw.rst @@ -0,0 +1,2 @@ +Skip asyncio test_create_datagram_endpoint_existing_sock_unix on platforms +lacking a functional bind() for named unix domain sockets. From webhook-mailer at python.org Wed Nov 20 19:17:07 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 00:17:07 -0000 Subject: [Python-checkins] bpo-38823: Clean up _xxtestfuzz initialization. (GH-17216) Message-ID: https://github.com/python/cpython/commit/e5d1f734db135e284af8e8868e7ccc85355952b9 commit: e5d1f734db135e284af8e8868e7ccc85355952b9 branch: master author: Brandt Bucher committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T16:17:02-08:00 summary: bpo-38823: Clean up _xxtestfuzz initialization. (GH-17216) https://bugs.python.org/issue38823 files: M Modules/_xxtestfuzz/_xxtestfuzz.c diff --git a/Modules/_xxtestfuzz/_xxtestfuzz.c b/Modules/_xxtestfuzz/_xxtestfuzz.c index 781dd23500a29..e0694de6719df 100644 --- a/Modules/_xxtestfuzz/_xxtestfuzz.c +++ b/Modules/_xxtestfuzz/_xxtestfuzz.c @@ -44,10 +44,5 @@ static struct PyModuleDef _fuzzmodule = { PyMODINIT_FUNC PyInit__xxtestfuzz(void) { - PyObject *m = NULL; - - if ((m = PyModule_Create(&_fuzzmodule)) == NULL) { - return NULL; - } - return m; + return PyModule_Create(&_fuzzmodule); } From webhook-mailer at python.org Wed Nov 20 19:27:57 2019 From: webhook-mailer at python.org (Lisa Roach) Date: Thu, 21 Nov 2019 00:27:57 -0000 Subject: [Python-checkins] bpo-38857: AsyncMock fix for awaitable values and StopIteration fix [3.8] (GH-17269) Message-ID: https://github.com/python/cpython/commit/046442d02bcc6e848e71e93e47f6cde9e279e993 commit: 046442d02bcc6e848e71e93e47f6cde9e279e993 branch: master author: Jason Fried committer: Lisa Roach date: 2019-11-20T16:27:51-08:00 summary: bpo-38857: AsyncMock fix for awaitable values and StopIteration fix [3.8] (GH-17269) files: A Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst A Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst M Doc/library/unittest.mock.rst M Lib/unittest/mock.py M Lib/unittest/test/testmock/testasync.py diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 7faecff84f63f..e92f5545d3eb0 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -873,7 +873,7 @@ object:: exception, - if ``side_effect`` is an iterable, the async function will return the next value of the iterable, however, if the sequence of result is - exhausted, ``StopIteration`` is raised immediately, + exhausted, ``StopAsyncIteration`` is raised immediately, - if ``side_effect`` is not defined, the async function will return the value defined by ``return_value``, hence, by default, the async function returns a new :class:`AsyncMock` object. diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index a48132c5b1cb5..b06e29cf01c95 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1139,8 +1139,8 @@ def _increment_mock_call(self, /, *args, **kwargs): _new_parent = _new_parent._mock_new_parent def _execute_mock_call(self, /, *args, **kwargs): - # seperate from _increment_mock_call so that awaited functions are - # executed seperately from their call + # separate from _increment_mock_call so that awaited functions are + # executed separately from their call, also AsyncMock overrides this method effect = self.side_effect if effect is not None: @@ -2136,29 +2136,45 @@ def __init__(self, /, *args, **kwargs): code_mock.co_flags = inspect.CO_COROUTINE self.__dict__['__code__'] = code_mock - async def _mock_call(self, /, *args, **kwargs): - try: - result = super()._mock_call(*args, **kwargs) - except (BaseException, StopIteration) as e: - side_effect = self.side_effect - if side_effect is not None and not callable(side_effect): - raise - return await _raise(e) + async def _execute_mock_call(self, /, *args, **kwargs): + # This is nearly just like super(), except for sepcial handling + # of coroutines _call = self.call_args + self.await_count += 1 + self.await_args = _call + self.await_args_list.append(_call) - async def proxy(): - try: - if inspect.isawaitable(result): - return await result - else: - return result - finally: - self.await_count += 1 - self.await_args = _call - self.await_args_list.append(_call) + effect = self.side_effect + if effect is not None: + if _is_exception(effect): + raise effect + elif not _callable(effect): + try: + result = next(effect) + except StopIteration: + # It is impossible to propogate a StopIteration + # through coroutines because of PEP 479 + raise StopAsyncIteration + if _is_exception(result): + raise result + elif asyncio.iscoroutinefunction(effect): + result = await effect(*args, **kwargs) + else: + result = effect(*args, **kwargs) - return await proxy() + if result is not DEFAULT: + return result + + if self._mock_return_value is not DEFAULT: + return self.return_value + + if self._mock_wraps is not None: + if asyncio.iscoroutinefunction(self._mock_wraps): + return await self._mock_wraps(*args, **kwargs) + return self._mock_wraps(*args, **kwargs) + + return self.return_value def assert_awaited(self): """ @@ -2864,10 +2880,6 @@ def seal(mock): seal(m) -async def _raise(exception): - raise exception - - class _AsyncIterator: """ Wraps an iterator in an asynchronous iterator. diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 0d2cdb0069ff7..149fd4deff102 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -358,42 +358,84 @@ def test_magicmock_lambda_spec(self): self.assertIsInstance(cm, MagicMock) -class AsyncArguments(unittest.TestCase): - def test_add_return_value(self): +class AsyncArguments(unittest.IsolatedAsyncioTestCase): + async def test_add_return_value(self): async def addition(self, var): return var + 1 mock = AsyncMock(addition, return_value=10) - output = asyncio.run(mock(5)) + output = await mock(5) self.assertEqual(output, 10) - def test_add_side_effect_exception(self): + async def test_add_side_effect_exception(self): async def addition(var): return var + 1 mock = AsyncMock(addition, side_effect=Exception('err')) with self.assertRaises(Exception): - asyncio.run(mock(5)) + await mock(5) - def test_add_side_effect_function(self): + async def test_add_side_effect_function(self): async def addition(var): return var + 1 mock = AsyncMock(side_effect=addition) - result = asyncio.run(mock(5)) + result = await mock(5) self.assertEqual(result, 6) - def test_add_side_effect_iterable(self): + async def test_add_side_effect_iterable(self): vals = [1, 2, 3] mock = AsyncMock(side_effect=vals) for item in vals: - self.assertEqual(item, asyncio.run(mock())) - - with self.assertRaises(RuntimeError) as e: - asyncio.run(mock()) - self.assertEqual( - e.exception, - RuntimeError('coroutine raised StopIteration') - ) + self.assertEqual(item, await mock()) + + with self.assertRaises(StopAsyncIteration) as e: + await mock() + + async def test_return_value_AsyncMock(self): + value = AsyncMock(return_value=10) + mock = AsyncMock(return_value=value) + result = await mock() + self.assertIs(result, value) + + async def test_return_value_awaitable(self): + fut = asyncio.Future() + fut.set_result(None) + mock = AsyncMock(return_value=fut) + result = await mock() + self.assertIsInstance(result, asyncio.Future) + + async def test_side_effect_awaitable_values(self): + fut = asyncio.Future() + fut.set_result(None) + + mock = AsyncMock(side_effect=[fut]) + result = await mock() + self.assertIsInstance(result, asyncio.Future) + + with self.assertRaises(StopAsyncIteration): + await mock() + + async def test_side_effect_is_AsyncMock(self): + effect = AsyncMock(return_value=10) + mock = AsyncMock(side_effect=effect) + + result = await mock() + self.assertEqual(result, 10) + + async def test_wraps_coroutine(self): + value = asyncio.Future() + + ran = False + async def inner(): + nonlocal ran + ran = True + return value + + mock = AsyncMock(wraps=inner) + result = await mock() + self.assertEqual(result, value) + mock.assert_awaited() + self.assertTrue(ran) class AsyncMagicMethods(unittest.TestCase): def test_async_magic_methods_return_async_mocks(self): diff --git a/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst b/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst new file mode 100644 index 0000000000000..f28df2811fb78 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst @@ -0,0 +1,4 @@ +AsyncMock fix for return values that are awaitable types. This also covers +side_effect iterable values that happend to be awaitable, and wraps +callables that return an awaitable type. Before these awaitables were being +awaited instead of being returned as is. diff --git a/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst b/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst new file mode 100644 index 0000000000000..c059539a1de60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst @@ -0,0 +1,3 @@ +AsyncMock now returns StopAsyncIteration on the exaustion of a side_effects +iterable. Since PEP-479 its Impossible to raise a StopIteration exception +from a coroutine. From webhook-mailer at python.org Wed Nov 20 20:19:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:19:14 -0000 Subject: [Python-checkins] Fixed an incorrect sentence in the docs (GH-17205) Message-ID: https://github.com/python/cpython/commit/06ca2a2be9374ac390e9407685ccce941ab9ffa2 commit: 06ca2a2be9374ac390e9407685ccce941ab9ffa2 branch: master author: Aveheuzed committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T17:19:00-08:00 summary: Fixed an incorrect sentence in the docs (GH-17205) Fixed an incorrect sentence in Doc/c-api/mapping.rst I fell on while translating the file. skip issue Automerge-Triggered-By: @csabella files: M Doc/c-api/mapping.rst diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 4015f43d8f1ee..6a80b033b651e 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -14,8 +14,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with a :meth:`__getitem__` method since in general case it is impossible to - determine what the type of keys it supports. This function always - succeeds. + determine what type of keys it supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) From webhook-mailer at python.org Wed Nov 20 20:24:56 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:24:56 -0000 Subject: [Python-checkins] Fixed an incorrect sentence in the docs (GH-17205) Message-ID: https://github.com/python/cpython/commit/7efeb75b720e097f087012cf45ecfbe1050b55ad commit: 7efeb75b720e097f087012cf45ecfbe1050b55ad branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T17:24:51-08:00 summary: Fixed an incorrect sentence in the docs (GH-17205) Fixed an incorrect sentence in Doc/c-api/mapping.rst I fell on while translating the file. skip issue Automerge-Triggered-By: @csabella (cherry picked from commit 06ca2a2be9374ac390e9407685ccce941ab9ffa2) Co-authored-by: Aveheuzed files: M Doc/c-api/mapping.rst diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 44cf2e7690892..abdc2aea758ba 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -14,8 +14,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with a :meth:`__getitem__` method since in general case it is impossible to - determine what the type of keys it supports. This function always - succeeds. + determine what type of keys it supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) From webhook-mailer at python.org Wed Nov 20 20:26:36 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:26:36 -0000 Subject: [Python-checkins] Fixed an incorrect sentence in the docs (GH-17205) Message-ID: https://github.com/python/cpython/commit/c5fe339b27c61ab37ddc8e6c5e8046075ed47fa6 commit: c5fe339b27c61ab37ddc8e6c5e8046075ed47fa6 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T17:26:30-08:00 summary: Fixed an incorrect sentence in the docs (GH-17205) Fixed an incorrect sentence in Doc/c-api/mapping.rst I fell on while translating the file. skip issue Automerge-Triggered-By: @csabella (cherry picked from commit 06ca2a2be9374ac390e9407685ccce941ab9ffa2) Co-authored-by: Aveheuzed files: M Doc/c-api/mapping.rst diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 4015f43d8f1ee..6a80b033b651e 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -14,8 +14,7 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with a :meth:`__getitem__` method since in general case it is impossible to - determine what the type of keys it supports. This function always - succeeds. + determine what type of keys it supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) From webhook-mailer at python.org Wed Nov 20 20:30:09 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:30:09 -0000 Subject: [Python-checkins] Removed capital letter in parameter in stdtypes.rst (GH-17218) Message-ID: https://github.com/python/cpython/commit/6db2fb7c300ca79d5585f2ae524ff4ca2707a7b6 commit: 6db2fb7c300ca79d5585f2ae524ff4ca2707a7b6 branch: master author: Jules Lasne (jlasne) committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T17:30:05-08:00 summary: Removed capital letter in parameter in stdtypes.rst (GH-17218) Automerge-Triggered-By: @csabella files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index b362cf5fa85e6..c4588f89c0662 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3667,7 +3667,7 @@ copying. :mod:`struct` module syntax. .. versionadded:: 3.8 - *Order* can be {'C', 'F', 'A'}. When *order* is 'C' or 'F', the data + *order* can be {'C', 'F', 'A'}. When *order* is 'C' or 'F', the data of the original array is converted to C or Fortran order. For contiguous views, 'A' returns an exact copy of the physical memory. In particular, in-memory Fortran order is preserved. For non-contiguous views, the From webhook-mailer at python.org Wed Nov 20 20:36:51 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:36:51 -0000 Subject: [Python-checkins] Removed capital letter in parameter in stdtypes.rst (GH-17218) Message-ID: https://github.com/python/cpython/commit/ac99ea4b308539dd8a25093974baf7b612c28c0c commit: ac99ea4b308539dd8a25093974baf7b612c28c0c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T17:36:46-08:00 summary: Removed capital letter in parameter in stdtypes.rst (GH-17218) Automerge-Triggered-By: @csabella (cherry picked from commit 6db2fb7c300ca79d5585f2ae524ff4ca2707a7b6) Co-authored-by: Jules Lasne (jlasne) files: M Doc/library/stdtypes.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index ceb562faaafbd..be72695462c7b 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3643,7 +3643,7 @@ copying. :mod:`struct` module syntax. .. versionadded:: 3.8 - *Order* can be {'C', 'F', 'A'}. When *order* is 'C' or 'F', the data + *order* can be {'C', 'F', 'A'}. When *order* is 'C' or 'F', the data of the original array is converted to C or Fortran order. For contiguous views, 'A' returns an exact copy of the physical memory. In particular, in-memory Fortran order is preserved. For non-contiguous views, the From webhook-mailer at python.org Wed Nov 20 20:49:20 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:49:20 -0000 Subject: [Python-checkins] bpo-36277: Add document for pdb debug and retval commands (GH-12872) Message-ID: https://github.com/python/cpython/commit/9391f6c3ef24f7962c534c42ccb792debdbef509 commit: 9391f6c3ef24f7962c534c42ccb792debdbef509 branch: master author: Dave Nguyen committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T17:49:15-08:00 summary: bpo-36277: Add document for pdb debug and retval commands (GH-12872) https://bugs.python.org/issue36277 Automerge-Triggered-By: @csabella files: M Doc/library/pdb.rst diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 0b9a687b14e3a..606e8e5345770 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -531,6 +531,14 @@ by the local file. Quit from the debugger. The program being executed is aborted. +.. pdbcommand:: debug code + + Enter a recursive debugger that steps through the code + argument (which is an arbitrary expression or statement to be + executed in the current environment). + +.. pdbcommand:: retval + Print the return value for the last return of a function. .. rubric:: Footnotes From webhook-mailer at python.org Wed Nov 20 20:56:30 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:56:30 -0000 Subject: [Python-checkins] bpo-36277: Add document for pdb debug and retval commands (GH-12872) Message-ID: https://github.com/python/cpython/commit/d5d41d39366214c9628b2680fa18fb8d085bcdbc commit: d5d41d39366214c9628b2680fa18fb8d085bcdbc branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T17:56:26-08:00 summary: bpo-36277: Add document for pdb debug and retval commands (GH-12872) https://bugs.python.org/issue36277 Automerge-Triggered-By: @csabella (cherry picked from commit 9391f6c3ef24f7962c534c42ccb792debdbef509) Co-authored-by: Dave Nguyen files: M Doc/library/pdb.rst diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index f26b6a8b553b3..5ee7faaa5c9f8 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -531,6 +531,14 @@ by the local file. Quit from the debugger. The program being executed is aborted. +.. pdbcommand:: debug code + + Enter a recursive debugger that steps through the code + argument (which is an arbitrary expression or statement to be + executed in the current environment). + +.. pdbcommand:: retval + Print the return value for the last return of a function. .. rubric:: Footnotes From webhook-mailer at python.org Wed Nov 20 20:56:48 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 01:56:48 -0000 Subject: [Python-checkins] bpo-36277: Add document for pdb debug and retval commands (GH-12872) Message-ID: https://github.com/python/cpython/commit/97c301bfc5ea278c32dc5fabe425d8981ec5d3b1 commit: 97c301bfc5ea278c32dc5fabe425d8981ec5d3b1 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T17:56:43-08:00 summary: bpo-36277: Add document for pdb debug and retval commands (GH-12872) https://bugs.python.org/issue36277 Automerge-Triggered-By: @csabella (cherry picked from commit 9391f6c3ef24f7962c534c42ccb792debdbef509) Co-authored-by: Dave Nguyen files: M Doc/library/pdb.rst diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index c7864e9e3f222..a52549feeca06 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -529,6 +529,14 @@ by the local file. Quit from the debugger. The program being executed is aborted. +.. pdbcommand:: debug code + + Enter a recursive debugger that steps through the code + argument (which is an arbitrary expression or statement to be + executed in the current environment). + +.. pdbcommand:: retval + Print the return value for the last return of a function. .. rubric:: Footnotes From webhook-mailer at python.org Wed Nov 20 21:10:24 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 02:10:24 -0000 Subject: [Python-checkins] Update functions.rst (GH-16468) Message-ID: https://github.com/python/cpython/commit/d67279147ace3b63187e5d75a15c345264f39e85 commit: d67279147ace3b63187e5d75a15c345264f39e85 branch: master author: G?ry Ogam committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-20T18:10:19-08:00 summary: Update functions.rst (GH-16468) This PR will make the following changes to the [_Built-in Functions_](https://docs.python.org/3/library/functions.html) chapter of the library documentation: - improve hyperlinks in Sphinx roles (trailing 's' belong to hyperlinks). Automerge-Triggered-By: @csabella files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 28b9649a16320..5abf978c88eec 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -473,7 +473,7 @@ are always available. They are listed here in alphabetical order. dictionary is omitted it defaults to the *globals* dictionary. If both dictionaries are omitted, the expression is executed with the *globals* and *locals* in the environment where :func:`eval` is called. Note, *eval()* - does not have access to the :term:`nested scope`\s (non-locals) in the + does not have access to the :term:`nested scopes ` (non-locals) in the enclosing environment. The return value is the result of @@ -1632,7 +1632,7 @@ are always available. They are listed here in alphabetical order. # super(C, self).method(arg) In addition to method lookups, :func:`super` also works for attribute - lookups. One possible use case for this is calling :term:`descriptor`\s + lookups. One possible use case for this is calling :term:`descriptors ` in a parent or sibling class. Note that :func:`super` is implemented as part of the binding process for From webhook-mailer at python.org Wed Nov 20 21:17:56 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 02:17:56 -0000 Subject: [Python-checkins] Update functions.rst (GH-16468) Message-ID: https://github.com/python/cpython/commit/23f9be24bc55b98dc86f87714b08073958f93485 commit: 23f9be24bc55b98dc86f87714b08073958f93485 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-20T18:17:51-08:00 summary: Update functions.rst (GH-16468) This PR will make the following changes to the [_Built-in Functions_](https://docs.python.org/3/library/functions.html) chapter of the library documentation: - improve hyperlinks in Sphinx roles (trailing 's' belong to hyperlinks). Automerge-Triggered-By: @csabella (cherry picked from commit d67279147ace3b63187e5d75a15c345264f39e85) Co-authored-by: G?ry Ogam files: M Doc/library/functions.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ca2a039ea43d7..7968eef4fb96b 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -471,7 +471,7 @@ are always available. They are listed here in alphabetical order. dictionary is omitted it defaults to the *globals* dictionary. If both dictionaries are omitted, the expression is executed with the *globals* and *locals* in the environment where :func:`eval` is called. Note, *eval()* - does not have access to the :term:`nested scope`\s (non-locals) in the + does not have access to the :term:`nested scopes ` (non-locals) in the enclosing environment. The return value is the result of @@ -1636,7 +1636,7 @@ are always available. They are listed here in alphabetical order. # super(C, self).method(arg) In addition to method lookups, :func:`super` also works for attribute - lookups. One possible use case for this is calling :term:`descriptor`\s + lookups. One possible use case for this is calling :term:`descriptors ` in a parent or sibling class. Note that :func:`super` is implemented as part of the binding process for From webhook-mailer at python.org Thu Nov 21 02:52:03 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 21 Nov 2019 07:52:03 -0000 Subject: [Python-checkins] bpo-38858: Allocate small integers on the heap (GH-17301) Message-ID: https://github.com/python/cpython/commit/5dcc06f6e0d7b5d6589085692b86c63e35e2325e commit: 5dcc06f6e0d7b5d6589085692b86c63e35e2325e branch: master author: Victor Stinner committer: GitHub date: 2019-11-21T08:51:59+01:00 summary: bpo-38858: Allocate small integers on the heap (GH-17301) Allocate small Python integers (small_ints of longobject.c) on the heap, rather than using static objects. files: M Objects/longobject.c diff --git a/Objects/longobject.c b/Objects/longobject.c index 2b57ea18666ee..294308e3e126d 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -40,7 +40,7 @@ PyObject *_PyLong_One = NULL; The integers that are preallocated are those in the range -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). */ -static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; +static PyLongObject* small_ints[NSMALLNEGINTS + NSMALLPOSINTS] = {0}; #define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS) @@ -52,9 +52,8 @@ Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs; static PyObject * get_small_int(sdigit ival) { - PyObject *v; assert(IS_SMALL_INT(ival)); - v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]; + PyObject *v = (PyObject*)small_ints[ival + NSMALLNEGINTS]; Py_INCREF(v); #ifdef COUNT_ALLOCS if (ival >= 0) @@ -5784,40 +5783,30 @@ int _PyLong_Init(void) { #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int ival, size; - PyLongObject *v = small_ints; - - for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { - size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); - if (Py_TYPE(v) == &PyLong_Type) { - /* The element is already initialized, most likely - * the Python interpreter was initialized before. - */ - Py_ssize_t refcnt; - PyObject* op = (PyObject*)v; - - refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op); - _Py_NewReference(op); - /* _Py_NewReference sets the ref count to 1 but - * the ref count might be larger. Set the refcnt - * to the original refcnt + 1 */ - Py_REFCNT(op) = refcnt + 1; - assert(Py_SIZE(op) == size); - assert(v->ob_digit[0] == (digit)abs(ival)); - } - else { - (void)PyObject_INIT(v, &PyLong_Type); + for (Py_ssize_t i=0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) { + sdigit ival = (sdigit)i - NSMALLNEGINTS; + int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + + PyLongObject *v = _PyLong_New(1); + if (!v) { + return -1; } + Py_SIZE(v) = size; v->ob_digit[0] = (digit)abs(ival); + + small_ints[i] = v; } #endif _PyLong_Zero = PyLong_FromLong(0); - if (_PyLong_Zero == NULL) + if (_PyLong_Zero == NULL) { return 0; + } + _PyLong_One = PyLong_FromLong(1); - if (_PyLong_One == NULL) + if (_PyLong_One == NULL) { return 0; + } /* initialize int_info */ if (Int_InfoType.tp_name == NULL) { @@ -5832,17 +5821,11 @@ _PyLong_Init(void) void _PyLong_Fini(void) { - /* Integers are currently statically allocated. Py_DECREF is not - needed, but Python must forget about the reference or multiple - reinitializations will fail. */ Py_CLEAR(_PyLong_One); Py_CLEAR(_PyLong_Zero); #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int i; - PyLongObject *v = small_ints; - for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { - _Py_DEC_REFTOTAL; - _Py_ForgetReference((PyObject*)v); + for (Py_ssize_t i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) { + Py_CLEAR(small_ints[i]); } #endif } From webhook-mailer at python.org Thu Nov 21 04:11:50 2019 From: webhook-mailer at python.org (Mark Shannon) Date: Thu, 21 Nov 2019 09:11:50 -0000 Subject: [Python-checkins] Produce cleaner bytecode for 'with' and 'async with' by generating separate code for normal and exceptional paths. (#6641) Message-ID: https://github.com/python/cpython/commit/fee552669f21ca294f57fe0df826945edc779090 commit: fee552669f21ca294f57fe0df826945edc779090 branch: master author: Mark Shannon committer: GitHub date: 2019-11-21T09:11:43Z summary: Produce cleaner bytecode for 'with' and 'async with' by generating separate code for normal and exceptional paths. (#6641) Remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY and POP_FINALLY bytecodes. Implement finally blocks by code duplication. Reimplement frame.lineno setter using line numbers rather than bytecode offsets. files: A Misc/NEWS.d/next/Core and Builtins/2018-03-13-14-46-03.bpo-32949.v821M7.rst M Doc/library/dis.rst M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_dis.py M Lib/test/test_sys_settrace.py M Objects/frameobject.c M Python/ceval.c M Python/compile.c M Python/importlib.h M Python/importlib_external.h M Python/importlib_zipimport.h M Python/opcode_targets.h M Python/peephole.c diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index b5243d0f364d8..2b55486f3a28e 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -706,50 +706,21 @@ iterations of the loop. popped values are used to restore the exception state. -.. opcode:: POP_FINALLY (preserve_tos) +.. opcode:: RERAISE - Cleans up the value stack and the block stack. If *preserve_tos* is not - ``0`` TOS first is popped from the stack and pushed on the stack after - performing other stack operations: + Re-raises the exception currently on top of the stack. - * If TOS is ``NULL`` or an integer (pushed by :opcode:`BEGIN_FINALLY` - or :opcode:`CALL_FINALLY`) it is popped from the stack. - * If TOS is an exception type (pushed when an exception has been raised) - 6 values are popped from the stack, the last three popped values are - used to restore the exception state. An exception handler block is - removed from the block stack. + .. versionadded:: 3.8 - It is similar to :opcode:`END_FINALLY`, but doesn't change the bytecode - counter nor raise an exception. Used for implementing :keyword:`break`, - :keyword:`continue` and :keyword:`return` in the :keyword:`finally` block. - .. versionadded:: 3.8 - - -.. opcode:: BEGIN_FINALLY - - Pushes ``NULL`` onto the stack for using it in :opcode:`END_FINALLY`, - :opcode:`POP_FINALLY`, :opcode:`WITH_CLEANUP_START` and - :opcode:`WITH_CLEANUP_FINISH`. Starts the :keyword:`finally` block. - - .. versionadded:: 3.8 +.. opcode:: WITH_EXCEPT_START + Calls the function in position 7 on the stack with the top three + items on the stack as arguments. + Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception + has occurred in a :keyword:`with` statement. -.. opcode:: END_FINALLY - - Terminates a :keyword:`finally` clause. The interpreter recalls whether the - exception has to be re-raised or execution has to be continued depending on - the value of TOS. - - * If TOS is ``NULL`` (pushed by :opcode:`BEGIN_FINALLY`) continue from - the next instruction. TOS is popped. - * If TOS is an integer (pushed by :opcode:`CALL_FINALLY`), sets the - bytecode counter to TOS. TOS is popped. - * If TOS is an exception type (pushed when an exception has been raised) - 6 values are popped from the stack, the first three popped values are - used to re-raise the exception and the last three popped values are used - to restore the exception state. An exception handler block is removed - from the block stack. + .. versionadded:: 3.8 .. opcode:: LOAD_ASSERTION_ERROR @@ -780,35 +751,6 @@ iterations of the loop. .. versionadded:: 3.2 -.. opcode:: WITH_CLEANUP_START - - Starts cleaning up the stack when a :keyword:`with` statement block exits. - - At the top of the stack are either ``NULL`` (pushed by - :opcode:`BEGIN_FINALLY`) or 6 values pushed if an exception has been - raised in the with block. Below is the context manager's - :meth:`~object.__exit__` or :meth:`~object.__aexit__` bound method. - - If TOS is ``NULL``, calls ``SECOND(None, None, None)``, - removes the function from the stack, leaving TOS, and pushes ``None`` - to the stack. Otherwise calls ``SEVENTH(TOP, SECOND, THIRD)``, - shifts the bottom 3 values of the stack down, replaces the empty spot - with ``NULL`` and pushes TOS. Finally pushes the result of the call. - - -.. opcode:: WITH_CLEANUP_FINISH - - Finishes cleaning up the stack when a :keyword:`with` statement block exits. - - TOS is result of ``__exit__()`` or ``__aexit__()`` function call pushed - by :opcode:`WITH_CLEANUP_START`. SECOND is ``None`` or an exception type - (pushed when an exception has been raised). - - Pops two values from the stack. If SECOND is not None and TOS is true - unwinds the EXCEPT_HANDLER block which was created when the exception - was caught and pushes ``NULL`` to the stack. - - All of the following opcodes use their arguments. .. opcode:: STORE_NAME (namei) @@ -1060,15 +1002,6 @@ All of the following opcodes use their arguments. stack. *delta* points to the finally block or the first except block. -.. opcode:: CALL_FINALLY (delta) - - Pushes the address of the next instruction onto the stack and increments - bytecode counter by *delta*. Used for calling the finally block as a - "subroutine". - - .. versionadded:: 3.8 - - .. opcode:: LOAD_FAST (var_num) Pushes a reference to the local ``co_varnames[var_num]`` onto the stack. diff --git a/Include/opcode.h b/Include/opcode.h index 95d56014860b3..712664224dc8e 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -30,10 +30,11 @@ extern "C" { #define BINARY_TRUE_DIVIDE 27 #define INPLACE_FLOOR_DIVIDE 28 #define INPLACE_TRUE_DIVIDE 29 +#define RERAISE 48 +#define WITH_EXCEPT_START 49 #define GET_AITER 50 #define GET_ANEXT 51 #define BEFORE_ASYNC_WITH 52 -#define BEGIN_FINALLY 53 #define END_ASYNC_FOR 54 #define INPLACE_ADD 55 #define INPLACE_SUBTRACT 56 @@ -59,14 +60,11 @@ extern "C" { #define INPLACE_AND 77 #define INPLACE_XOR 78 #define INPLACE_OR 79 -#define WITH_CLEANUP_START 81 -#define WITH_CLEANUP_FINISH 82 #define RETURN_VALUE 83 #define IMPORT_STAR 84 #define SETUP_ANNOTATIONS 85 #define YIELD_VALUE 86 #define POP_BLOCK 87 -#define END_FINALLY 88 #define POP_EXCEPT 89 #define HAVE_ARGUMENT 90 #define STORE_NAME 90 @@ -127,8 +125,6 @@ extern "C" { #define BUILD_TUPLE_UNPACK_WITH_CALL 158 #define LOAD_METHOD 160 #define CALL_METHOD 161 -#define CALL_FINALLY 162 -#define POP_FINALLY 163 /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 825ed77c3d4b6..d62c6cb77cddd 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -272,6 +272,8 @@ def _write_atomic(path, data, mode=0o666): # only args in ast.arguments #37593) # Python 3.8b4 3413 (Fix "break" and "continue" in "finally" #37830) # Python 3.9a0 3420 (add LOAD_ASSERTION_ERROR #34880) +# Python 3.9a0 3421 (simplified bytecode for with blocks #32949) +# Python 3.9a0 3422 (remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY, POP_FINALLY bytecodes #33387) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -280,7 +282,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3420).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3422).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index 0ae0068f2f22b..1898a38abbb0d 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -84,10 +84,12 @@ def jabs_op(name, op): def_op('INPLACE_FLOOR_DIVIDE', 28) def_op('INPLACE_TRUE_DIVIDE', 29) +def_op('RERAISE', 48) +def_op('WITH_EXCEPT_START', 49) def_op('GET_AITER', 50) def_op('GET_ANEXT', 51) def_op('BEFORE_ASYNC_WITH', 52) -def_op('BEGIN_FINALLY', 53) + def_op('END_ASYNC_FOR', 54) def_op('INPLACE_ADD', 55) def_op('INPLACE_SUBTRACT', 56) @@ -115,14 +117,13 @@ def jabs_op(name, op): def_op('INPLACE_AND', 77) def_op('INPLACE_XOR', 78) def_op('INPLACE_OR', 79) -def_op('WITH_CLEANUP_START', 81) -def_op('WITH_CLEANUP_FINISH', 82) + def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) def_op('SETUP_ANNOTATIONS', 85) def_op('YIELD_VALUE', 86) def_op('POP_BLOCK', 87) -def_op('END_FINALLY', 88) + def_op('POP_EXCEPT', 89) HAVE_ARGUMENT = 90 # Opcodes from here have an argument: @@ -210,7 +211,5 @@ def jabs_op(name, op): name_op('LOAD_METHOD', 160) def_op('CALL_METHOD', 161) -jrel_op('CALL_FINALLY', 162) -def_op('POP_FINALLY', 163) del def_op, name_op, jrel_op, jabs_op diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index fecf203cc9b5f..5c1595268c505 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -278,32 +278,34 @@ def bug1333982(x=[]): --> 6 BINARY_TRUE_DIVIDE 8 POP_TOP 10 POP_BLOCK - 12 JUMP_FORWARD 40 (to 54) + 12 JUMP_FORWARD 44 (to 58) %3d >> 14 DUP_TOP 16 LOAD_GLOBAL 0 (Exception) 18 COMPARE_OP 10 (exception match) - 20 POP_JUMP_IF_FALSE 52 + 20 POP_JUMP_IF_FALSE 56 22 POP_TOP 24 STORE_FAST 0 (e) 26 POP_TOP - 28 SETUP_FINALLY 10 (to 40) + 28 SETUP_FINALLY 18 (to 48) %3d 30 LOAD_FAST 0 (e) 32 LOAD_ATTR 1 (__traceback__) 34 STORE_FAST 1 (tb) 36 POP_BLOCK - 38 BEGIN_FINALLY - >> 40 LOAD_CONST 0 (None) + 38 POP_EXCEPT + 40 LOAD_CONST 0 (None) 42 STORE_FAST 0 (e) 44 DELETE_FAST 0 (e) - 46 END_FINALLY - 48 POP_EXCEPT - 50 JUMP_FORWARD 2 (to 54) - >> 52 END_FINALLY - -%3d >> 54 LOAD_FAST 1 (tb) - 56 RETURN_VALUE + 46 JUMP_FORWARD 10 (to 58) + >> 48 LOAD_CONST 0 (None) + 50 STORE_FAST 0 (e) + 52 DELETE_FAST 0 (e) + 54 RERAISE + >> 56 RERAISE + +%3d >> 58 LOAD_FAST 1 (tb) + 60 RETURN_VALUE """ % (TRACEBACK_CODE.co_firstlineno + 1, TRACEBACK_CODE.co_firstlineno + 2, TRACEBACK_CODE.co_firstlineno + 3, @@ -752,7 +754,7 @@ def f(c=c): Positional-only arguments: 0 Kw-only arguments: 0 Number of locals: 2 -Stack size: 10 +Stack size: 9 Flags: OPTIMIZED, NEWLOCALS, NOFREE, COROUTINE Constants: 0: None @@ -977,10 +979,10 @@ def jumpy(): Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=96, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=100, starts_line=None, is_jump_target=False), - Instruction(opname='SETUP_FINALLY', opcode=122, arg=70, argval=174, argrepr='to 174', offset=102, starts_line=20, is_jump_target=True), + Instruction(opname='SETUP_FINALLY', opcode=122, arg=98, argval=202, argrepr='to 202', offset=102, starts_line=20, is_jump_target=True), Instruction(opname='SETUP_FINALLY', opcode=122, arg=12, argval=118, argrepr='to 118', offset=104, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False), Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=110, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False), Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=114, starts_line=None, is_jump_target=False), @@ -993,33 +995,47 @@ def jumpy(): Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=132, starts_line=23, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=134, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=134, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=136, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False), Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=140, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=170, argrepr='to 170', offset=142, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=46, argval=190, argrepr='to 190', offset=142, starts_line=None, is_jump_target=False), + Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=144, starts_line=None, is_jump_target=True), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=146, starts_line=25, is_jump_target=True), - Instruction(opname='SETUP_WITH', opcode=143, arg=14, argval=164, argrepr='to 164', offset=148, starts_line=None, is_jump_target=False), + Instruction(opname='SETUP_WITH', opcode=143, arg=24, argval=174, argrepr='to 174', offset=148, starts_line=None, is_jump_target=False), Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=150, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=152, starts_line=26, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=154, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=156, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=158, starts_line=None, is_jump_target=False), Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False), - Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False), - Instruction(opname='WITH_CLEANUP_START', opcode=81, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=True), - Instruction(opname='WITH_CLEANUP_FINISH', opcode=82, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=True), - Instruction(opname='BEGIN_FINALLY', opcode=53, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=174, starts_line=28, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=176, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=178, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=184, starts_line=None, is_jump_target=False), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=162, starts_line=None, is_jump_target=False), + Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=164, starts_line=None, is_jump_target=False), + Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=3, argval=3, argrepr='', offset=168, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=190, argrepr='to 190', offset=172, starts_line=None, is_jump_target=False), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=True), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=180, argval=180, argrepr='', offset=176, starts_line=None, is_jump_target=False), + Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=True), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=184, starts_line=None, is_jump_target=False), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=192, starts_line=28, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=194, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=196, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=198, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=10, argval=212, argrepr='to 212', offset=200, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=202, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=204, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='', offset=206, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=208, starts_line=None, is_jump_target=False), + Instruction(opname='RERAISE', opcode=48, arg=None, argval=None, argrepr='', offset=210, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=212, starts_line=None, is_jump_target=True), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=214, starts_line=None, is_jump_target=False) ] # One last piece of inspect fodder to check the default line number handling @@ -1032,6 +1048,10 @@ def simple(): pass class InstructionTests(BytecodeTestCase): + def __init__(self, *args): + super().__init__(*args) + self.maxDiff = None + def test_default_first_line(self): actual = dis.get_instructions(simple) self.assertEqual(list(actual), expected_opinfo_simple) @@ -1063,6 +1083,7 @@ def test_jumpy(self): # get_instructions has its own tests above, so can rely on it to validate # the object oriented API class BytecodeTests(unittest.TestCase): + def test_instantiation(self): # Test with function, method, code string and code object for obj in [_f, _C(1).__init__, "a=1", _f.__code__]: diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index d4e1ac2c83eff..0af015aa56bb4 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -1431,7 +1431,7 @@ def test_no_jump_from_exception_event(output): 1 / 0 @jump_test(3, 2, [2], event='return', error=(ValueError, - "can't jump from a yield statement")) + "can't jump from a 'yield' statement")) def test_no_jump_from_yield(output): def gen(): output.append(2) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-13-14-46-03.bpo-32949.v821M7.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-13-14-46-03.bpo-32949.v821M7.rst new file mode 100644 index 0000000000000..16b3058ee68bb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-13-14-46-03.bpo-32949.v821M7.rst @@ -0,0 +1,5 @@ +Removed WITH_CLEANUP_START, WITH_CLEANUP_FINISH, BEGIN_FINALLY, END_FINALLY, CALL_FINALLY and POP_FINALLY bytecodes. +Replaced with RERAISE and WITH_EXCEPT_FINISH bytecodes. +The compiler now generates different code for exceptional and non-exceptional branches for 'with' and 'try-except' +statements. For 'try-finally' statements the 'finally' block is replicated for each exit from the 'try' body. + diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 27ef9ff259024..d7acb41f7a3a1 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -66,6 +66,285 @@ get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) return oparg; } +typedef struct _codetracker { + unsigned char *code; + Py_ssize_t code_len; + unsigned char *lnotab; + Py_ssize_t lnotab_len; + int start_line; + int offset; + int line; + int addr; + int line_addr; +} codetracker; + +/* Reset the mutable parts of the tracker */ +static void +reset(codetracker *tracker) +{ + tracker->offset = 0; + tracker->addr = 0; + tracker->line_addr = 0; + tracker->line = tracker->start_line; +} + +/* Initialise the tracker */ +static void +init_codetracker(codetracker *tracker, PyCodeObject *code_obj) +{ + PyBytes_AsStringAndSize(code_obj->co_code, + (char **)&tracker->code, &tracker->code_len); + PyBytes_AsStringAndSize(code_obj->co_lnotab, + (char **)&tracker->lnotab, &tracker->lnotab_len); + tracker->start_line = code_obj->co_firstlineno; + reset(tracker); +} + +static void +advance_tracker(codetracker *tracker) +{ + tracker->addr += sizeof(_Py_CODEUNIT); + if (tracker->offset >= tracker->lnotab_len) { + return; + } + while (tracker->offset < tracker->lnotab_len && + tracker->addr >= tracker->line_addr + tracker->lnotab[tracker->offset]) { + tracker->line_addr += tracker->lnotab[tracker->offset]; + tracker->line += (signed char)tracker->lnotab[tracker->offset+1]; + tracker->offset += 2; + } +} + + +static void +retreat_tracker(codetracker *tracker) +{ + tracker->addr -= sizeof(_Py_CODEUNIT); + while (tracker->addr < tracker->line_addr) { + tracker->offset -= 2; + tracker->line_addr -= tracker->lnotab[tracker->offset]; + tracker->line -= (signed char)tracker->lnotab[tracker->offset+1]; + } +} + +static int +move_to_addr(codetracker *tracker, int addr) +{ + while (addr > tracker->addr) { + advance_tracker(tracker); + if (tracker->addr >= tracker->code_len) { + return -1; + } + } + while (addr < tracker->addr) { + retreat_tracker(tracker); + if (tracker->addr < 0) { + return -1; + } + } + return 0; +} + +static int +first_line_not_before(codetracker *tracker, int line) +{ + int result = INT_MAX; + reset(tracker); + while (tracker->addr < tracker->code_len) { + if (tracker->line == line) { + return line; + } + if (tracker->line > line && tracker->line < result) { + result = tracker->line; + } + advance_tracker(tracker); + } + if (result == INT_MAX) { + return -1; + } + return result; +} + +static int +move_to_nearest_start_of_line(codetracker *tracker, int line) +{ + if (line > tracker->line) { + while (line != tracker->line) { + advance_tracker(tracker); + if (tracker->addr >= tracker->code_len) { + return -1; + } + } + } + else { + while (line != tracker->line) { + retreat_tracker(tracker); + if (tracker->addr < 0) { + return -1; + } + } + while (tracker->addr > tracker->line_addr) { + retreat_tracker(tracker); + } + } + return 0; +} + +typedef struct _blockitem +{ + unsigned char kind; + int end_addr; + int start_line; +} blockitem; + +typedef struct _blockstack +{ + blockitem stack[CO_MAXBLOCKS]; + int depth; +} blockstack; + + +static void +init_blockstack(blockstack *blocks) +{ + blocks->depth = 0; +} + +static void +push_block(blockstack *blocks, unsigned char kind, + int end_addr, int start_line) +{ + assert(blocks->depth < CO_MAXBLOCKS); + blocks->stack[blocks->depth].kind = kind; + blocks->stack[blocks->depth].end_addr = end_addr; + blocks->stack[blocks->depth].start_line = start_line; + blocks->depth++; +} + +static unsigned char +pop_block(blockstack *blocks) +{ + assert(blocks->depth > 0); + blocks->depth--; + return blocks->stack[blocks->depth].kind; +} + +static blockitem * +top_block(blockstack *blocks) +{ + assert(blocks->depth > 0); + return &blocks->stack[blocks->depth-1]; +} + +static inline int +is_try_except(unsigned char op, int target_op) +{ + return op == SETUP_FINALLY && (target_op == DUP_TOP || target_op == POP_TOP); +} + +static inline int +is_async_for(unsigned char op, int target_op) +{ + return op == SETUP_FINALLY && target_op == END_ASYNC_FOR; +} + +static inline int +is_try_finally(unsigned char op, int target_op) +{ + return op == SETUP_FINALLY && !is_try_except(op, target_op) && !is_async_for(op, target_op); +} + +/* Kind for finding except blocks in the jump to line code */ +#define TRY_EXCEPT 250 + +static int +block_stack_for_line(codetracker *tracker, int line, blockstack *blocks) +{ + if (line < tracker->start_line) { + return -1; + } + init_blockstack(blocks); + reset(tracker); + while (tracker->addr < tracker->code_len) { + if (tracker->line == line) { + return 0; + } + if (blocks->depth > 0 && tracker->addr == top_block(blocks)->end_addr) { + unsigned char kind = pop_block(blocks); + assert(kind != SETUP_FINALLY); + if (kind == TRY_EXCEPT) { + push_block(blocks, POP_EXCEPT, -1, tracker->line); + } + if (kind == SETUP_WITH || kind == SETUP_ASYNC_WITH) { + push_block(blocks, WITH_EXCEPT_START, -1, tracker->line); + } + } + unsigned char op = tracker->code[tracker->addr]; + if (op == SETUP_FINALLY || op == SETUP_ASYNC_WITH || op == SETUP_WITH || op == FOR_ITER) { + unsigned int oparg = get_arg((const _Py_CODEUNIT *)tracker->code, + tracker->addr / sizeof(_Py_CODEUNIT)); + int target_addr = tracker->addr + oparg + sizeof(_Py_CODEUNIT); + int target_op = tracker->code[target_addr]; + if (is_async_for(op, target_op)) { + push_block(blocks, FOR_ITER, target_addr, tracker->line); + } + else if (op == FOR_ITER) { + push_block(blocks, FOR_ITER, target_addr-sizeof(_Py_CODEUNIT), tracker->line); + } + else if (is_try_except(op, target_op)) { + push_block(blocks, TRY_EXCEPT, target_addr-sizeof(_Py_CODEUNIT), tracker->line); + } + else if (is_try_finally(op, target_op)) { + int addr = tracker->addr; + // Skip over duplicate 'finally' blocks if line is after body. + move_to_addr(tracker, target_addr); + if (tracker->line > line) { + // Target is in body, rewind to start. + move_to_addr(tracker, addr); + push_block(blocks, op, target_addr, tracker->line); + } + else { + // Now in finally block. + push_block(blocks, RERAISE, -1, tracker->line); + } + } + else { + push_block(blocks, op, target_addr, tracker->line); + } + } + else if (op == RERAISE) { + assert(blocks->depth > 0); + unsigned char kind = top_block(blocks)->kind; + if (kind == RERAISE || kind == WITH_EXCEPT_START || kind == POP_EXCEPT) { + pop_block(blocks); + } + + } + advance_tracker(tracker); + } + return -1; +} + +static void +frame_stack_pop(PyFrameObject *f) +{ + PyObject *v = (*--f->f_stacktop); + Py_DECREF(v); +} + +static void +frame_block_unwind(PyFrameObject *f) +{ + assert(f->f_iblock > 0); + f->f_iblock--; + PyTryBlock *b = &f->f_blockstack[f->f_iblock]; + int delta = (f->f_stacktop - f->f_valuestack) - b->b_level; + while (delta > 0) { + frame_stack_pop(f); + delta--; + } +} + /* Setter for f_lineno - you can set f_lineno from within a trace function in * order to jump to a given line of code, subject to some restrictions. Most @@ -77,7 +356,8 @@ get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) * o Lines with an 'except' statement on them can't be jumped to, because * they expect an exception to be on the top of the stack. * o Lines that live in a 'finally' block can't be jumped from or to, since - * the END_FINALLY expects to clean up the stack after the 'try' block. + * we cannot be sure which state the interpreter was in or would be in + * during execution of the finally block. * o 'try', 'with' and 'async with' blocks can't be jumped into because * the blockstack needs to be set up before their code runs. * o 'for' and 'async for' loops can't be jumped into because the @@ -89,22 +369,6 @@ get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) static int frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored)) { - int new_lineno = 0; /* The new value of f_lineno */ - long l_new_lineno; - int overflow; - int new_lasti = 0; /* The new value of f_lasti */ - unsigned char *code = NULL; /* The bytecode for the frame... */ - Py_ssize_t code_len = 0; /* ...and its length */ - unsigned char *lnotab = NULL; /* Iterating over co_lnotab */ - Py_ssize_t lnotab_len = 0; /* (ditto) */ - int offset = 0; /* (ditto) */ - int line = 0; /* (ditto) */ - int addr = 0; /* (ditto) */ - int delta_iblock = 0; /* Scanning the SETUPs and POPs */ - int delta = 0; - int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ - int blockstack_top = 0; /* (ditto) */ - if (p_new_lineno == NULL) { PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); return -1; @@ -145,189 +409,131 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } - /* Fail if the line comes before the start of the code block. */ - l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); - if (overflow + + codetracker tracker; + init_codetracker(&tracker, f->f_code); + move_to_addr(&tracker, f->f_lasti); + int current_line = tracker.line; + assert(current_line >= 0); + int new_lineno; + + { + /* Fail if the line falls outside the code block and + select first line with actual code. */ + int overflow; + long l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow); + if (overflow #if SIZEOF_LONG > SIZEOF_INT - || l_new_lineno > INT_MAX - || l_new_lineno < INT_MIN + || l_new_lineno > INT_MAX + || l_new_lineno < INT_MIN #endif - ) { - PyErr_SetString(PyExc_ValueError, - "lineno out of range"); - return -1; - } - new_lineno = (int)l_new_lineno; + ) { + PyErr_SetString(PyExc_ValueError, + "lineno out of range"); + return -1; + } + new_lineno = (int)l_new_lineno; - if (new_lineno < f->f_code->co_firstlineno) { - PyErr_Format(PyExc_ValueError, - "line %d comes before the current code block", - new_lineno); - return -1; - } - else if (new_lineno == f->f_code->co_firstlineno) { - new_lasti = 0; - new_lineno = f->f_code->co_firstlineno; - } - else { - /* Find the bytecode offset for the start of the given - * line, or the first code-owning line after it. */ - char *tmp; - PyBytes_AsStringAndSize(f->f_code->co_lnotab, - &tmp, &lnotab_len); - lnotab = (unsigned char *) tmp; - addr = 0; - line = f->f_code->co_firstlineno; - new_lasti = -1; - for (offset = 0; offset < lnotab_len; offset += 2) { - addr += lnotab[offset]; - line += (signed char)lnotab[offset+1]; - if (line >= new_lineno) { - new_lasti = addr; - new_lineno = line; - break; - } + if (new_lineno < f->f_code->co_firstlineno) { + PyErr_Format(PyExc_ValueError, + "line %d comes before the current code block", + new_lineno); + return -1; + } + + new_lineno = first_line_not_before(&tracker, new_lineno); + if (new_lineno < 0) { + PyErr_Format(PyExc_ValueError, + "line %d comes after the current code block", + (int)l_new_lineno); + return -1; } } - /* If we didn't reach the requested line, return an error. */ - if (new_lasti == -1) { - PyErr_Format(PyExc_ValueError, - "line %d comes after the current code block", - new_lineno); + if (tracker.code[f->f_lasti] == YIELD_VALUE || tracker.code[f->f_lasti] == YIELD_FROM) { + PyErr_SetString(PyExc_ValueError, + "can't jump from a 'yield' statement"); return -1; } - /* We're now ready to look at the bytecode. */ - PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len); + /* Find block stack for current line and target line. */ + blockstack current_stack, new_stack; + block_stack_for_line(&tracker, new_lineno, &new_stack); + block_stack_for_line(&tracker, current_line, ¤t_stack); /* The trace function is called with a 'return' trace event after the * execution of a yield statement. */ - assert(f->f_lasti != -1); - if (code[f->f_lasti] == YIELD_VALUE || code[f->f_lasti] == YIELD_FROM) { - PyErr_SetString(PyExc_ValueError, - "can't jump from a yield statement"); - return -1; - } - - /* You can't jump onto a line with an 'except' statement on it - - * they expect to have an exception on the top of the stack, which - * won't be true if you jump to them. They always start with code - * that either pops the exception using POP_TOP (plain 'except:' - * lines do this) or duplicates the exception on the stack using - * DUP_TOP (if there's an exception type specified). See compile.c, - * 'com_try_except' for the full details. There aren't any other - * cases (AFAIK) where a line's code can start with DUP_TOP or - * POP_TOP, but if any ever appear, they'll be subject to the same - * restriction (but with a different error message). */ - if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) { + if (tracker.code[tracker.addr] == DUP_TOP || tracker.code[tracker.addr] == POP_TOP) { PyErr_SetString(PyExc_ValueError, "can't jump to 'except' line as there's no exception"); return -1; } - /* You can't jump into or out of a 'finally' block because the 'try' - * block leaves something on the stack for the END_FINALLY to clean up. - * So we walk the bytecode, maintaining a simulated blockstack. - * 'blockstack' is a stack of the bytecode addresses of the starts of - * the 'finally' blocks. */ - memset(blockstack, '\0', sizeof(blockstack)); - blockstack_top = 0; - unsigned char prevop = NOP; - for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) { - unsigned char op = code[addr]; - switch (op) { - case SETUP_FINALLY: - case SETUP_WITH: - case SETUP_ASYNC_WITH: - case FOR_ITER: { - unsigned int oparg = get_arg((const _Py_CODEUNIT *)code, - addr / sizeof(_Py_CODEUNIT)); - int target_addr = addr + oparg + sizeof(_Py_CODEUNIT); - assert(target_addr < code_len); - /* Police block-jumping (you can't jump into the middle of a block) - * and ensure that the blockstack finishes up in a sensible state (by - * popping any blocks we're jumping out of). We look at all the - * blockstack operations between the current position and the new - * one, and keep track of how many blocks we drop out of on the way. - * By also keeping track of the lowest blockstack position we see, we - * can tell whether the jump goes into any blocks without coming out - * again - in that case we raise an exception below. */ - int first_in = addr < f->f_lasti && f->f_lasti < target_addr; - int second_in = addr < new_lasti && new_lasti < target_addr; - if (!first_in && second_in) { - PyErr_SetString(PyExc_ValueError, - "can't jump into the middle of a block"); - return -1; + /* Validate change of block stack. */ + if (new_stack.depth > 0) { + blockitem *current_block_at_new_depth = &(current_stack.stack[new_stack.depth-1]); + if (new_stack.depth > current_stack.depth || + top_block(&new_stack)->start_line != current_block_at_new_depth->start_line) { + unsigned char target_kind = top_block(&new_stack)->kind; + char *msg; + if (target_kind == POP_EXCEPT) { + msg = "can't jump into an 'except' block as there's no exception"; } - int in_for_loop = op == FOR_ITER || code[target_addr] == END_ASYNC_FOR; - if (first_in && !second_in) { - if (!delta_iblock) { - if (in_for_loop) { - /* Pop the iterators of any 'for' and 'async for' loop - * we're jumping out of. */ - delta++; - } - else if (prevop == LOAD_CONST) { - /* Pops None pushed before SETUP_FINALLY. */ - delta++; - } - } - if (!in_for_loop) { - delta_iblock++; - } + else if (target_kind == RERAISE) { + msg = "can't jump into a 'finally' block"; } - if (!in_for_loop) { - blockstack[blockstack_top++] = target_addr; + else { + msg = "can't jump into the middle of a block"; } - break; + PyErr_SetString(PyExc_ValueError, msg); + return -1; } + } - case END_FINALLY: { - assert(blockstack_top > 0); - int target_addr = blockstack[--blockstack_top]; - assert(target_addr <= addr); - int first_in = target_addr <= f->f_lasti && f->f_lasti <= addr; - int second_in = target_addr <= new_lasti && new_lasti <= addr; - if (first_in != second_in) { - op = code[target_addr]; - PyErr_Format(PyExc_ValueError, - "can't jump %s %s block", - second_in ? "into" : "out of", - (op == DUP_TOP || op == POP_TOP) ? - "an 'except'" : "a 'finally'"); - return -1; - } - break; - } - } - prevop = op; - } - - /* Verify that the blockstack tracking code didn't get lost. */ - assert(blockstack_top == 0); - - /* Pop any blocks that we're jumping out of. */ - if (delta_iblock > 0) { - f->f_iblock -= delta_iblock; - PyTryBlock *b = &f->f_blockstack[f->f_iblock]; - delta += (int)(f->f_stacktop - f->f_valuestack) - b->b_level; - if (b->b_type == SETUP_FINALLY && - code[b->b_handler] == WITH_CLEANUP_START) - { - /* Pop the exit function. */ - delta++; + /* Check for illegal jumps out of finally or except blocks. */ + for (int depth = new_stack.depth; depth < current_stack.depth; depth++) { + switch(current_stack.stack[depth].kind) { + case RERAISE: + PyErr_SetString(PyExc_ValueError, + "can't jump out of a 'finally' block"); + return -1; + case POP_EXCEPT: + PyErr_SetString(PyExc_ValueError, + "can't jump out of an 'except' block"); + return -1; } } - while (delta > 0) { - PyObject *v = (*--f->f_stacktop); - Py_DECREF(v); - delta--; + + /* Unwind block stack. */ + while (current_stack.depth > new_stack.depth) { + unsigned char kind = pop_block(¤t_stack); + switch(kind) { + case FOR_ITER: + frame_stack_pop(f); + break; + case SETUP_FINALLY: + case TRY_EXCEPT: + frame_block_unwind(f); + break; + case SETUP_WITH: + case SETUP_ASYNC_WITH: + frame_block_unwind(f); + // Pop the exit function + frame_stack_pop(f); + break; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected block kind"); + return -1; + } } + move_to_addr(&tracker, f->f_lasti); + move_to_nearest_start_of_line(&tracker, new_lineno); + /* Finally set the new f_lineno and f_lasti and return OK. */ f->f_lineno = new_lineno; - f->f_lasti = new_lasti; + f->f_lasti = tracker.addr; return 0; } diff --git a/Python/ceval.c b/Python/ceval.c index ee13fd1ad7043..96ed329b0d995 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -79,7 +79,7 @@ static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -2017,7 +2017,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { + int opcode_at_minus_3 = 0; + if ((next_instr - first_instr) > 2) { + opcode_at_minus_3 = _Py_OPCODE(next_instr[-3]); + } format_awaitable_error(tstate, Py_TYPE(iterable), + opcode_at_minus_3, _Py_OPCODE(next_instr[-2])); } @@ -2128,104 +2133,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } - case TARGET(POP_FINALLY): { - /* If oparg is 0 at the top of the stack are 1 or 6 values: - Either: - - TOP = NULL or an integer - or: - - (TOP, SECOND, THIRD) = exc_info() - - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER - - If oparg is 1 the value for 'return' was additionally pushed - at the top of the stack. - */ - PyObject *res = NULL; - if (oparg) { - res = POP(); - } - PyObject *exc = POP(); - if (exc == NULL || PyLong_CheckExact(exc)) { - Py_XDECREF(exc); - } - else { - Py_DECREF(exc); - Py_DECREF(POP()); - Py_DECREF(POP()); - - PyObject *type, *value, *traceback; - _PyErr_StackItem *exc_info; - PyTryBlock *b = PyFrame_BlockPop(f); - if (b->b_type != EXCEPT_HANDLER) { - _PyErr_SetString(tstate, PyExc_SystemError, - "popped block is not an except handler"); - Py_XDECREF(res); - goto error; - } - assert(STACK_LEVEL() == (b)->b_level + 3); - exc_info = tstate->exc_info; - type = exc_info->exc_type; - value = exc_info->exc_value; - traceback = exc_info->exc_traceback; - exc_info->exc_type = POP(); - exc_info->exc_value = POP(); - exc_info->exc_traceback = POP(); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - } - if (oparg) { - PUSH(res); - } - DISPATCH(); - } - - case TARGET(CALL_FINALLY): { - PyObject *ret = PyLong_FromLong(INSTR_OFFSET()); - if (ret == NULL) { - goto error; - } - PUSH(ret); - JUMPBY(oparg); - FAST_DISPATCH(); - } - - case TARGET(BEGIN_FINALLY): { - /* Push NULL onto the stack for using it in END_FINALLY, - POP_FINALLY, WITH_CLEANUP_START and WITH_CLEANUP_FINISH. - */ - PUSH(NULL); - FAST_DISPATCH(); - } - - case TARGET(END_FINALLY): { - PREDICTED(END_FINALLY); - /* At the top of the stack are 1 or 6 values: - Either: - - TOP = NULL or an integer - or: - - (TOP, SECOND, THIRD) = exc_info() - - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER - */ + case TARGET(RERAISE): { PyObject *exc = POP(); - if (exc == NULL) { - FAST_DISPATCH(); - } - else if (PyLong_CheckExact(exc)) { - int ret = _PyLong_AsInt(exc); - Py_DECREF(exc); - if (ret == -1 && _PyErr_Occurred(tstate)) { - goto error; - } - JUMPTO(ret); - FAST_DISPATCH(); - } - else { - assert(PyExceptionClass_Check(exc)); - PyObject *val = POP(); - PyObject *tb = POP(); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } + PyObject *val = POP(); + PyObject *tb = POP(); + assert(PyExceptionClass_Check(exc)); + PyErr_Restore(exc, val, tb); + goto exception_unwind; } case TARGET(END_ASYNC_FOR): { @@ -3302,111 +3216,31 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } - case TARGET(WITH_CLEANUP_START): { - /* At the top of the stack are 1 or 6 values indicating - how/why we entered the finally clause: - - TOP = NULL + case TARGET(WITH_EXCEPT_START): { + /* At the top of the stack are 7 values: - (TOP, SECOND, THIRD) = exc_info() - (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER - Below them is EXIT, the context.__exit__ or context.__aexit__ - bound method. - In the first case, we must call - EXIT(None, None, None) - otherwise we must call - EXIT(TOP, SECOND, THIRD) - - In the first case, we remove EXIT from the - stack, leaving TOP, and push TOP on the stack. - Otherwise we shift the bottom 3 values of the - stack down, replace the empty spot with NULL, and push - None on the stack. - - Finally we push the result of the call. + - (FOURTH, FIFTH, SIXTH) = previous exception for EXCEPT_HANDLER + - SEVENTH: the context.__exit__ bound method + We call SEVENTH(TOP, SECOND, THIRD). + Then we push again the TOP exception and the __exit__ + return value. */ PyObject *exit_func; PyObject *exc, *val, *tb, *res; - val = tb = Py_None; exc = TOP(); - if (exc == NULL) { - STACK_SHRINK(1); - exit_func = TOP(); - SET_TOP(exc); - exc = Py_None; - } - else { - assert(PyExceptionClass_Check(exc)); - PyObject *tp2, *exc2, *tb2; - PyTryBlock *block; - val = SECOND(); - tb = THIRD(); - tp2 = FOURTH(); - exc2 = PEEK(5); - tb2 = PEEK(6); - exit_func = PEEK(7); - SET_VALUE(7, tb2); - SET_VALUE(6, exc2); - SET_VALUE(5, tp2); - /* UNWIND_EXCEPT_HANDLER will pop this off. */ - SET_FOURTH(NULL); - /* We just shifted the stack down, so we have - to tell the except handler block that the - values are lower than it expects. */ - assert(f->f_iblock > 0); - block = &f->f_blockstack[f->f_iblock - 1]; - assert(block->b_type == EXCEPT_HANDLER); - assert(block->b_level > 0); - block->b_level--; - } - + val = SECOND(); + tb = THIRD(); + assert(exc != Py_None); + assert(!PyLong_Check(exc)); + exit_func = PEEK(7); PyObject *stack[4] = {NULL, exc, val, tb}; res = _PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - Py_DECREF(exit_func); if (res == NULL) goto error; - Py_INCREF(exc); /* Duplicating the exception on the stack */ - PUSH(exc); PUSH(res); - PREDICT(WITH_CLEANUP_FINISH); - DISPATCH(); - } - - case TARGET(WITH_CLEANUP_FINISH): { - PREDICTED(WITH_CLEANUP_FINISH); - /* TOP = the result of calling the context.__exit__ bound method - SECOND = either None or exception type - - If SECOND is None below is NULL or the return address, - otherwise below are 7 values representing an exception. - */ - PyObject *res = POP(); - PyObject *exc = POP(); - int err; - - if (exc != Py_None) - err = PyObject_IsTrue(res); - else - err = 0; - - Py_DECREF(res); - Py_DECREF(exc); - - if (err < 0) - goto error; - else if (err > 0) { - /* There was an exception and a True return. - * We must manually unwind the EXCEPT_HANDLER block - * which was created when the exception was caught, - * otherwise the stack will be in an inconsistent state. - */ - PyTryBlock *b = PyFrame_BlockPop(f); - assert(b->b_type == EXCEPT_HANDLER); - UNWIND_EXCEPT_HANDLER(b); - PUSH(NULL); - } - PREDICT(END_FINALLY); DISPATCH(); } @@ -3776,6 +3610,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PUSH(val); PUSH(exc); JUMPTO(handler); + if (_Py_TracingPossible(ceval)) { + /* Make sure that we trace line after exception */ + instr_prev = INT_MAX; + } /* Resume normal execution */ goto main_loop; } @@ -5477,7 +5315,7 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) } static void -format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode) +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevopcode, int prevopcode) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { if (prevopcode == BEFORE_ASYNC_WITH) { @@ -5486,7 +5324,7 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode "that does not implement __await__: %.100s", type->tp_name); } - else if (prevopcode == WITH_CLEANUP_START) { + else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL_FUNCTION && prevprevopcode == DUP_TOP)) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aexit__ " "that does not implement __await__: %.100s", diff --git a/Python/compile.c b/Python/compile.c index f26ad3c775255..f56c015fb96a3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -81,14 +81,16 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_TRY2, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP }; +enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE }; struct fblockinfo { enum fblocktype fb_type; basicblock *fb_block; /* (optional) type-specific exit or cleanup block */ basicblock *fb_exit; + /* (optional) additional information required for unwinding */ + void *fb_datum; }; enum { @@ -960,12 +962,6 @@ stack_effect(int opcode, int oparg, int jump) * Restore the stack position and push 6 values before jumping to * the handler if an exception be raised. */ return jump ? 6 : 1; - case WITH_CLEANUP_START: - return 2; /* or 1, depending on TOS */ - case WITH_CLEANUP_FINISH: - /* Pop a variable number of values pushed by WITH_CLEANUP_START - * + __exit__ or __aexit__. */ - return -3; case RETURN_VALUE: return -1; case IMPORT_STAR: @@ -980,10 +976,6 @@ stack_effect(int opcode, int oparg, int jump) return 0; case POP_EXCEPT: return -3; - case END_FINALLY: - case POP_FINALLY: - /* Pop 6 values when an exception was raised. */ - return -6; case STORE_NAME: return -1; @@ -1056,14 +1048,11 @@ stack_effect(int opcode, int oparg, int jump) * Restore the stack position and push 6 values before jumping to * the handler if an exception be raised. */ return jump ? 6 : 0; - case BEGIN_FINALLY: - /* Actually pushes 1 value, but count 6 for balancing with - * END_FINALLY and POP_FINALLY. - * This is the main reason of using this opcode instead of - * "LOAD_CONST None". */ - return 6; - case CALL_FINALLY: - return jump ? 1 : 0; + case RERAISE: + return -3; + + case WITH_EXCEPT_START: + return 1; case LOAD_FAST: return 1; @@ -1629,7 +1618,7 @@ find_ann(asdl_seq *stmts) static int compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, - basicblock *exit) + basicblock *exit, void *datum) { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { @@ -1641,6 +1630,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, f->fb_type = t; f->fb_block = b; f->fb_exit = exit; + f->fb_datum = datum; return 1; } @@ -1654,8 +1644,19 @@ compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) assert(u->u_fblock[u->u_nfblocks].fb_block == b); } +static int +compiler_call_exit_with_nones(struct compiler *c) { + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, DUP_TOP); + ADDOP(c, DUP_TOP); + ADDOP_I(c, CALL_FUNCTION, 3); + return 1; +} + /* Unwind a frame block. If preserve_tos is true, the TOS before - * popping the blocks will be restored afterwards. + * popping the blocks will be restored afterwards, unless another + * return, break or continue is found. In which case, the TOS will + * be popped. */ static int compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, @@ -1665,15 +1666,6 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, case WHILE_LOOP: return 1; - case FINALLY_END: - info->fb_exit = NULL; - ADDOP_I(c, POP_FINALLY, preserve_tos); - if (preserve_tos) { - ADDOP(c, ROT_TWO); - } - ADDOP(c, POP_TOP); - return 1; - case FOR_LOOP: /* Pop the iterator */ if (preserve_tos) { @@ -1688,20 +1680,28 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, case FINALLY_TRY: ADDOP(c, POP_BLOCK); - ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + if (preserve_tos) { + if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { + return 0; + } + } + VISIT_SEQ(c, stmt, info->fb_datum); + if (preserve_tos) { + compiler_pop_fblock(c, POP_VALUE, NULL); + } return 1; - - case FINALLY_TRY2: - ADDOP(c, POP_BLOCK); + + case FINALLY_END: if (preserve_tos) { - ADDOP(c, ROT_TWO); - ADDOP(c, POP_TOP); - ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + ADDOP(c, ROT_FOUR); } - else { - ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); - ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + if (preserve_tos) { + ADDOP(c, ROT_FOUR); } + ADDOP(c, POP_EXCEPT); return 1; case WITH: @@ -1710,34 +1710,66 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, if (preserve_tos) { ADDOP(c, ROT_TWO); } - ADDOP(c, BEGIN_FINALLY); - ADDOP(c, WITH_CLEANUP_START); + if(!compiler_call_exit_with_nones(c)) { + return 0; + } if (info->fb_type == ASYNC_WITH) { ADDOP(c, GET_AWAITABLE); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); } - ADDOP(c, WITH_CLEANUP_FINISH); - ADDOP_I(c, POP_FINALLY, 0); + ADDOP(c, POP_TOP); return 1; case HANDLER_CLEANUP: + if (info->fb_datum) { + ADDOP(c, POP_BLOCK); + } if (preserve_tos) { ADDOP(c, ROT_FOUR); } - if (info->fb_exit) { - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_JREL(c, CALL_FINALLY, info->fb_exit); + ADDOP(c, POP_EXCEPT); + if (info->fb_datum) { + ADDOP_LOAD_CONST(c, Py_None); + compiler_nameop(c, info->fb_datum, Store); + compiler_nameop(c, info->fb_datum, Del); } - else { - ADDOP(c, POP_EXCEPT); + return 1; + + case POP_VALUE: + if (preserve_tos) { + ADDOP(c, ROT_TWO); } + ADDOP(c, POP_TOP); return 1; } Py_UNREACHABLE(); } +/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */ +static int +compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) { + if (c->u->u_nfblocks == 0) { + return 1; + } + struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1]; + if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) { + *loop = top; + return 1; + } + struct fblockinfo copy = *top; + c->u->u_nfblocks--; + if (!compiler_unwind_fblock(c, ©, preserve_tos)) { + return 0; + } + if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) { + return 0; + } + c->u->u_fblock[c->u->u_nfblocks] = copy; + c->u->u_nfblocks++; + return 1; +} + /* Compile a sequence of statements, checking for a docstring and for annotations. */ @@ -2634,10 +2666,12 @@ compiler_if(struct compiler *c, stmt_ty s) if (next == NULL) return 0; } - else + else { next = end; - if (!compiler_jump_if(c, s->v.If.test, next, 0)) + } + if (!compiler_jump_if(c, s->v.If.test, next, 0)) { return 0; + } VISIT_SEQ(c, stmt, s->v.If.body); if (asdl_seq_LEN(s->v.If.orelse)) { ADDOP_JREL(c, JUMP_FORWARD, end); @@ -2657,12 +2691,12 @@ compiler_for(struct compiler *c, stmt_ty s) start = compiler_new_block(c); cleanup = compiler_new_block(c); end = compiler_new_block(c); - if (start == NULL || end == NULL || cleanup == NULL) + if (start == NULL || end == NULL || cleanup == NULL) { return 0; - - if (!compiler_push_fblock(c, FOR_LOOP, start, end)) + } + if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { return 0; - + } VISIT(c, expr, s->v.For.iter); ADDOP(c, GET_ITER); compiler_use_next_block(c, start); @@ -2694,16 +2728,16 @@ compiler_async_for(struct compiler *c, stmt_ty s) except = compiler_new_block(c); end = compiler_new_block(c); - if (start == NULL || except == NULL || end == NULL) + if (start == NULL || except == NULL || end == NULL) { return 0; - + } VISIT(c, expr, s->v.AsyncFor.iter); ADDOP(c, GET_AITER); compiler_use_next_block(c, start); - if (!compiler_push_fblock(c, FOR_LOOP, start, end)) + if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { return 0; - + } /* SETUP_FINALLY to guard the __anext__ call */ ADDOP_JREL(c, SETUP_FINALLY, except); ADDOP(c, GET_ANEXT); @@ -2741,7 +2775,7 @@ compiler_while(struct compiler *c, stmt_ty s) // Push a dummy block so the VISIT_SEQ knows that we are // inside a while loop so it can correctly evaluate syntax // errors. - if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL)) { + if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL, NULL)) { return 0; } VISIT_SEQ(c, stmt, s->v.While.body); @@ -2771,7 +2805,7 @@ compiler_while(struct compiler *c, stmt_ty s) orelse = NULL; compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, WHILE_LOOP, loop, end)) + if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) return 0; if (constant == -1) { if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) @@ -2811,12 +2845,8 @@ compiler_return(struct compiler *c, stmt_ty s) if (preserve_tos) { VISIT(c, expr, s->v.Return.value); } - for (int depth = c->u->u_nfblocks; depth--;) { - struct fblockinfo *info = &c->u->u_fblock[depth]; - - if (!compiler_unwind_fblock(c, info, preserve_tos)) - return 0; - } + if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) + return 0; if (s->v.Return.value == NULL) { ADDOP_LOAD_CONST(c, Py_None); } @@ -2831,33 +2861,32 @@ compiler_return(struct compiler *c, stmt_ty s) static int compiler_break(struct compiler *c) { - for (int depth = c->u->u_nfblocks; depth--;) { - struct fblockinfo *info = &c->u->u_fblock[depth]; - - if (!compiler_unwind_fblock(c, info, 0)) - return 0; - if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { - ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_exit); - return 1; - } + struct fblockinfo *loop = NULL; + if (!compiler_unwind_fblock_stack(c, 0, &loop)) { + return 0; + } + if (loop == NULL) { + return compiler_error(c, "'break' outside loop"); + } + if (!compiler_unwind_fblock(c, loop, 0)) { + return 0; } - return compiler_error(c, "'break' outside loop"); + ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_exit); + return 1; } static int compiler_continue(struct compiler *c) { - for (int depth = c->u->u_nfblocks; depth--;) { - struct fblockinfo *info = &c->u->u_fblock[depth]; - - if (info->fb_type == WHILE_LOOP || info->fb_type == FOR_LOOP) { - ADDOP_JABS(c, JUMP_ABSOLUTE, info->fb_block); - return 1; - } - if (!compiler_unwind_fblock(c, info, 0)) - return 0; + struct fblockinfo *loop = NULL; + if (!compiler_unwind_fblock_stack(c, 0, &loop)) { + return 0; } - return compiler_error(c, "'continue' not properly in loop"); + if (loop == NULL) { + return compiler_error(c, "'continue' not properly in loop"); + } + ADDOP_JABS(c, JUMP_ABSOLUTE, loop->fb_block); + return 1; } @@ -2866,10 +2895,11 @@ compiler_continue(struct compiler *c) SETUP_FINALLY L POP_BLOCK - BEGIN_FINALLY + + JUMP E L: - END_FINALLY + E: The special instructions use the block stack. Each block stack entry contains the instruction that created it (here @@ -2881,11 +2911,6 @@ compiler_continue(struct compiler *c) onto the block stack. POP_BLOCK: Pops en entry from the block stack. - BEGIN_FINALLY - Pushes NULL onto the value stack. - END_FINALLY: - Pops 1 (NULL or int) or 6 entries from the *value* stack and restore - the raised and the caught exceptions they specify. The block stack is unwound when an exception is raised: when a SETUP_FINALLY entry is found, the raised and the caught @@ -2897,47 +2922,18 @@ compiler_continue(struct compiler *c) static int compiler_try_finally(struct compiler *c, stmt_ty s) { - basicblock *start, *newcurblock, *body, *end; - int break_finally = 1; + basicblock *body, *end, *exit; body = compiler_new_block(c); end = compiler_new_block(c); - if (body == NULL || end == NULL) + exit = compiler_new_block(c); + if (body == NULL || end == NULL || exit == NULL) return 0; - start = c->u->u_curblock; - - /* `finally` block. Compile it first to determine if any of "break", - "continue" or "return" are used in it. */ - compiler_use_next_block(c, end); - if (!compiler_push_fblock(c, FINALLY_END, end, end)) - return 0; - VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP(c, END_FINALLY); - break_finally = (c->u->u_fblock[c->u->u_nfblocks - 1].fb_exit == NULL); - if (break_finally) { - /* Pops a placeholder. See below */ - ADDOP(c, POP_TOP); - } - compiler_pop_fblock(c, FINALLY_END, end); - - newcurblock = c->u->u_curblock; - c->u->u_curblock = start; - start->b_next = NULL; - /* `try` block */ - c->u->u_lineno_set = 0; - c->u->u_lineno = s->lineno; - c->u->u_col_offset = s->col_offset; - if (break_finally) { - /* Pushes a placeholder for the value of "return" in the "try" block - to balance the stack for "break", "continue" and "return" in - the "finally" block. */ - ADDOP_LOAD_CONST(c, Py_None); - } ADDOP_JREL(c, SETUP_FINALLY, end); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body, end)) + if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) return 0; if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { if (!compiler_try_except(c, s)) @@ -2947,12 +2943,17 @@ compiler_try_finally(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.Try.body); } ADDOP(c, POP_BLOCK); - ADDOP(c, BEGIN_FINALLY); - compiler_pop_fblock(c, break_finally ? FINALLY_TRY2 : FINALLY_TRY, body); - - c->u->u_curblock->b_next = end; - c->u->u_curblock = newcurblock; - + compiler_pop_fblock(c, FINALLY_TRY, body); + VISIT_SEQ(c, stmt, s->v.Try.finalbody); + ADDOP_JREL(c, JUMP_FORWARD, exit); + /* `finally` block */ + compiler_use_next_block(c, end); + if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) + return 0; + VISIT_SEQ(c, stmt, s->v.Try.finalbody); + compiler_pop_fblock(c, FINALLY_END, end); + ADDOP(c, RERAISE); + compiler_use_next_block(c, exit); return 1; } @@ -2981,7 +2982,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) [tb, val, exc] L2: DUP .............................etc....................... - [tb, val, exc] Ln+1: END_FINALLY # re-raise exception + [tb, val, exc] Ln+1: RERAISE # re-raise exception [] L0: @@ -3001,7 +3002,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) return 0; ADDOP_JREL(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, EXCEPT, body, NULL)) + if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); @@ -3053,28 +3054,29 @@ compiler_try_except(struct compiler *c, stmt_ty s) /* second try: */ ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, cleanup_end)) + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) return 0; /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - ADDOP(c, POP_BLOCK); - ADDOP(c, BEGIN_FINALLY); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + ADDOP(c, POP_BLOCK); + ADDOP(c, POP_EXCEPT); + /* name = None; del name */ + ADDOP_LOAD_CONST(c, Py_None); + compiler_nameop(c, handler->v.ExceptHandler.name, Store); + compiler_nameop(c, handler->v.ExceptHandler.name, Del); + ADDOP_JREL(c, JUMP_FORWARD, end); - /* finally: */ + /* except: */ compiler_use_next_block(c, cleanup_end); - if (!compiler_push_fblock(c, FINALLY_END, cleanup_end, NULL)) - return 0; /* name = None; del name */ ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP(c, END_FINALLY); - ADDOP(c, POP_EXCEPT); - compiler_pop_fblock(c, FINALLY_END, cleanup_end); + ADDOP(c, RERAISE); } else { basicblock *cleanup_body; @@ -3086,16 +3088,16 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_TOP); ADDOP(c, POP_TOP); compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL)) + if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - ADDOP(c, POP_EXCEPT); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); + ADDOP(c, POP_EXCEPT); + ADDOP_JREL(c, JUMP_FORWARD, end); } - ADDOP_JREL(c, JUMP_FORWARD, end); compiler_use_next_block(c, except); } - ADDOP(c, END_FINALLY); + ADDOP(c, RERAISE); compiler_use_next_block(c, orelse); VISIT_SEQ(c, stmt, s->v.Try.orelse); compiler_use_next_block(c, end); @@ -4630,6 +4632,22 @@ expr_constant(expr_ty e) return -1; } +static int +compiler_with_except_finish(struct compiler *c) { + basicblock *exit; + exit = compiler_new_block(c); + if (exit == NULL) + return 0; + ADDOP_JABS(c, POP_JUMP_IF_TRUE, exit); + ADDOP(c, RERAISE); + compiler_use_next_block(c, exit); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_EXCEPT); + ADDOP(c, POP_TOP); + return 1; +} /* Implements the async with statement. @@ -4658,7 +4676,7 @@ expr_constant(expr_ty e) static int compiler_async_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *finally; + basicblock *block, *final, *exit; withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); assert(s->kind == AsyncWith_kind); @@ -4669,8 +4687,9 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) } block = compiler_new_block(c); - finally = compiler_new_block(c); - if (!block || !finally) + final = compiler_new_block(c); + exit = compiler_new_block(c); + if (!block || !final || !exit) return 0; /* Evaluate EXPR */ @@ -4681,11 +4700,11 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); - ADDOP_JREL(c, SETUP_ASYNC_WITH, finally); + ADDOP_JREL(c, SETUP_ASYNC_WITH, final); /* SETUP_ASYNC_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, ASYNC_WITH, block, finally)) { + if (!compiler_push_fblock(c, ASYNC_WITH, block, final, NULL)) { return 0; } @@ -4704,76 +4723,80 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) else if (!compiler_async_with(c, s, pos)) return 0; - /* End of try block; start the finally block */ - ADDOP(c, POP_BLOCK); - ADDOP(c, BEGIN_FINALLY); compiler_pop_fblock(c, ASYNC_WITH, block); + ADDOP(c, POP_BLOCK); + /* End of body; start the cleanup */ - compiler_use_next_block(c, finally); - if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) + /* For successful outcome: + * call __exit__(None, None, None) + */ + if(!compiler_call_exit_with_nones(c)) return 0; + ADDOP(c, GET_AWAITABLE); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, YIELD_FROM); - /* Finally block starts; context.__exit__ is on the stack under - the exception or return information. Just issue our magic - opcode. */ - ADDOP(c, WITH_CLEANUP_START); + ADDOP(c, POP_TOP); + + ADDOP_JABS(c, JUMP_ABSOLUTE, exit); + + /* For exceptional outcome: */ + compiler_use_next_block(c, final); + ADDOP(c, WITH_EXCEPT_START); ADDOP(c, GET_AWAITABLE); ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, YIELD_FROM); + compiler_with_except_finish(c); - ADDOP(c, WITH_CLEANUP_FINISH); - - /* Finally block ends. */ - ADDOP(c, END_FINALLY); - compiler_pop_fblock(c, FINALLY_END, finally); +compiler_use_next_block(c, exit); return 1; } /* Implements the with statement from PEP 343. - - The semantics outlined in that PEP are as follows: - with EXPR as VAR: BLOCK - - It is implemented roughly as: - - context = EXPR - exit = context.__exit__ # not calling it - value = context.__enter__() - try: - VAR = value # if VAR present in the syntax - BLOCK - finally: - if an exception was raised: - exc = copy of (exception, instance, traceback) - else: - exc = (None, None, None) - exit(*exc) + is implemented as: + + SETUP_WITH E + or POP_TOP + + LOAD_CONST (None, None, None) + CALL_FUNCTION_EX 0 + JUMP_FORWARD EXIT + E: WITH_EXCEPT_START (calls EXPR.__exit__) + POP_JUMP_IF_TRUE T: + RERAISE + T: POP_TOP * 3 (remove exception from stack) + POP_EXCEPT + POP_TOP + EXIT: */ + static int compiler_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *finally; + basicblock *block, *final, *exit; withitem_ty item = asdl_seq_GET(s->v.With.items, pos); assert(s->kind == With_kind); block = compiler_new_block(c); - finally = compiler_new_block(c); - if (!block || !finally) + final = compiler_new_block(c); + exit = compiler_new_block(c); + if (!block || !final || !exit) return 0; /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); - ADDOP_JREL(c, SETUP_WITH, finally); + /* Will push bound __exit__ */ + ADDOP_JREL(c, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, WITH, block, finally)) { + if (!compiler_push_fblock(c, WITH, block, final, NULL)) { return 0; } @@ -4792,24 +4815,26 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) else if (!compiler_with(c, s, pos)) return 0; - /* End of try block; start the finally block */ ADDOP(c, POP_BLOCK); - ADDOP(c, BEGIN_FINALLY); compiler_pop_fblock(c, WITH, block); - - compiler_use_next_block(c, finally); - if (!compiler_push_fblock(c, FINALLY_END, finally, NULL)) + + /* End of body; start the cleanup. */ + + /* For successful outcome: + * call __exit__(None, None, None) + */ + if (!compiler_call_exit_with_nones(c)) return 0; + ADDOP(c, POP_TOP); + ADDOP_JREL(c, JUMP_FORWARD, exit); - /* Finally block starts; context.__exit__ is on the stack under - the exception or return information. Just issue our magic - opcode. */ - ADDOP(c, WITH_CLEANUP_START); - ADDOP(c, WITH_CLEANUP_FINISH); + /* For exceptional outcome: */ + compiler_use_next_block(c, final); - /* Finally block ends. */ - ADDOP(c, END_FINALLY); - compiler_pop_fblock(c, FINALLY_END, finally); + ADDOP(c, WITH_EXCEPT_START); + compiler_with_except_finish(c); + + compiler_use_next_block(c, exit); return 1; } @@ -5427,7 +5452,7 @@ Py_LOCAL_INLINE(void) stackdepth_push(basicblock ***sp, basicblock *b, int depth) { assert(b->b_startdepth < 0 || b->b_startdepth == depth); - if (b->b_startdepth < depth) { + if (b->b_startdepth < depth && b->b_startdepth < 100) { assert(b->b_startdepth < 0); b->b_startdepth = depth; *(*sp)++ = b; @@ -5483,19 +5508,14 @@ stackdepth(struct compiler *c) maxdepth = target_depth; } assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ - if (instr->i_opcode == CALL_FINALLY) { - assert(instr->i_target->b_startdepth >= 0); - assert(instr->i_target->b_startdepth >= target_depth); - depth = new_depth; - continue; - } stackdepth_push(&sp, instr->i_target, target_depth); } depth = new_depth; if (instr->i_opcode == JUMP_ABSOLUTE || instr->i_opcode == JUMP_FORWARD || instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS) + instr->i_opcode == RAISE_VARARGS || + instr->i_opcode == RERAISE) { /* remaining code is dead */ next = NULL; diff --git a/Python/importlib.h b/Python/importlib.h index 67c820cd0364e..d837bdd9d4c53 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -133,19 +133,21 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 2,8,1,6,2,10,1,8,1,4,1,6,1,8,1,122, 24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115, 95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,9,0,0,0,67,0, - 0,0,115,178,0,0,0,116,0,160,1,161,0,125,1,124, - 0,116,2,124,1,60,0,122,148,124,0,106,3,143,110,1, + 0,0,0,0,0,0,2,0,0,0,8,0,0,0,67,0, + 0,0,115,210,0,0,0,116,0,160,1,161,0,125,1,124, + 0,116,2,124,1,60,0,122,180,124,0,106,3,143,126,1, 0,124,0,106,4,100,1,107,2,115,46,124,0,106,5,124, - 1,107,2,114,84,124,1,124,0,95,5,124,0,4,0,106, - 4,100,2,55,0,2,0,95,4,87,0,53,0,81,0,82, - 0,163,0,87,0,162,86,100,3,83,0,124,0,160,6,161, - 0,114,104,116,7,100,4,124,0,22,0,131,1,130,1,124, - 0,106,8,160,9,100,5,161,1,114,130,124,0,4,0,106, - 10,100,2,55,0,2,0,95,10,87,0,53,0,81,0,82, - 0,88,0,124,0,106,8,160,9,161,0,1,0,124,0,106, - 8,160,11,161,0,1,0,113,18,87,0,53,0,116,2,124, - 1,61,0,88,0,100,6,83,0,41,7,122,185,10,32,32, + 1,107,2,114,90,124,1,124,0,95,5,124,0,4,0,106, + 4,100,2,55,0,2,0,95,4,87,0,100,3,4,0,4, + 0,131,3,1,0,87,0,116,2,124,1,61,0,100,4,83, + 0,124,0,160,6,161,0,114,110,116,7,100,5,124,0,22, + 0,131,1,130,1,124,0,106,8,160,9,100,6,161,1,114, + 136,124,0,4,0,106,10,100,2,55,0,2,0,95,10,87, + 0,100,3,4,0,4,0,131,3,1,0,110,16,49,0,115, + 156,48,0,1,0,1,0,1,0,89,0,1,0,124,0,106, + 8,160,9,161,0,1,0,124,0,106,8,160,11,161,0,1, + 0,113,18,87,0,116,2,124,1,61,0,110,8,116,2,124, + 1,61,0,48,0,100,3,83,0,41,7,122,185,10,32,32, 32,32,32,32,32,32,65,99,113,117,105,114,101,32,116,104, 101,32,109,111,100,117,108,101,32,108,111,99,107,46,32,32, 73,102,32,97,32,112,111,116,101,110,116,105,97,108,32,100, @@ -158,193 +160,196 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 99,113,117,105,114,101,100,32,97,110,100,32,84,114,117,101, 32,105,115,32,114,101,116,117,114,110,101,100,46,10,32,32, 32,32,32,32,32,32,114,22,0,0,0,233,1,0,0,0, - 84,122,23,100,101,97,100,108,111,99,107,32,100,101,116,101, - 99,116,101,100,32,98,121,32,37,114,70,78,41,12,114,23, + 78,84,122,23,100,101,97,100,108,111,99,107,32,100,101,116, + 101,99,116,101,100,32,98,121,32,37,114,70,41,12,114,23, 0,0,0,114,32,0,0,0,114,33,0,0,0,114,24,0, 0,0,114,27,0,0,0,114,26,0,0,0,114,36,0,0, 0,114,19,0,0,0,114,25,0,0,0,218,7,97,99,113, 117,105,114,101,114,28,0,0,0,218,7,114,101,108,101,97, 115,101,169,2,114,30,0,0,0,114,35,0,0,0,114,10, 0,0,0,114,10,0,0,0,114,11,0,0,0,114,38,0, - 0,0,78,0,0,0,115,30,0,0,0,0,6,8,1,8, - 1,2,2,8,1,20,1,6,1,14,1,18,1,8,1,12, - 1,12,1,24,2,10,1,16,2,122,19,95,77,111,100,117, - 108,101,76,111,99,107,46,97,99,113,117,105,114,101,99,1, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,9, - 0,0,0,67,0,0,0,115,122,0,0,0,116,0,160,1, - 161,0,125,1,124,0,106,2,143,98,1,0,124,0,106,3, - 124,1,107,3,114,34,116,4,100,1,131,1,130,1,124,0, - 106,5,100,2,107,4,115,48,74,0,130,1,124,0,4,0, - 106,5,100,3,56,0,2,0,95,5,124,0,106,5,100,2, - 107,2,114,108,100,0,124,0,95,3,124,0,106,6,114,108, - 124,0,4,0,106,6,100,3,56,0,2,0,95,6,124,0, - 106,7,160,8,161,0,1,0,87,0,53,0,81,0,82,0, - 88,0,100,0,83,0,41,4,78,250,31,99,97,110,110,111, - 116,32,114,101,108,101,97,115,101,32,117,110,45,97,99,113, - 117,105,114,101,100,32,108,111,99,107,114,22,0,0,0,114, - 37,0,0,0,41,9,114,23,0,0,0,114,32,0,0,0, - 114,24,0,0,0,114,26,0,0,0,218,12,82,117,110,116, - 105,109,101,69,114,114,111,114,114,27,0,0,0,114,28,0, - 0,0,114,25,0,0,0,114,39,0,0,0,114,40,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,39,0,0,0,103,0,0,0,115,22,0,0,0,0,1, - 8,1,8,1,10,1,8,1,14,1,14,1,10,1,6,1, - 6,1,14,1,122,19,95,77,111,100,117,108,101,76,111,99, - 107,46,114,101,108,101,97,115,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,18,0,0,0,100,1,160,0,124,0,106,1,116, - 2,124,0,131,1,161,2,83,0,41,2,78,122,23,95,77, - 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32, - 97,116,32,123,125,169,3,218,6,102,111,114,109,97,116,114, - 17,0,0,0,218,2,105,100,169,1,114,30,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,95,114,101,112,114,95,95,116,0,0,0,115,2,0,0, - 0,0,1,122,20,95,77,111,100,117,108,101,76,111,99,107, - 46,95,95,114,101,112,114,95,95,78,41,9,114,1,0,0, - 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, - 114,31,0,0,0,114,36,0,0,0,114,38,0,0,0,114, - 39,0,0,0,114,47,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,20,0, - 0,0,52,0,0,0,115,12,0,0,0,8,1,4,5,8, - 8,8,12,8,25,8,13,114,20,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,48,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,83,0,41,11,218,16,95,68, - 117,109,109,121,77,111,100,117,108,101,76,111,99,107,122,86, - 65,32,115,105,109,112,108,101,32,95,77,111,100,117,108,101, - 76,111,99,107,32,101,113,117,105,118,97,108,101,110,116,32, - 102,111,114,32,80,121,116,104,111,110,32,98,117,105,108,100, - 115,32,119,105,116,104,111,117,116,10,32,32,32,32,109,117, - 108,116,105,45,116,104,114,101,97,100,105,110,103,32,115,117, - 112,112,111,114,116,46,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, - 16,0,0,0,124,1,124,0,95,0,100,1,124,0,95,1, - 100,0,83,0,114,21,0,0,0,41,2,114,17,0,0,0, - 114,27,0,0,0,114,29,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,31,0,0,0,124,0, - 0,0,115,4,0,0,0,0,1,6,1,122,25,95,68,117, - 109,109,121,77,111,100,117,108,101,76,111,99,107,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,3,0,0,0,67,0,0,0,115, - 18,0,0,0,124,0,4,0,106,0,100,1,55,0,2,0, - 95,0,100,2,83,0,41,3,78,114,37,0,0,0,84,41, - 1,114,27,0,0,0,114,46,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,38,0,0,0,128, - 0,0,0,115,4,0,0,0,0,1,14,1,122,24,95,68, - 117,109,109,121,77,111,100,117,108,101,76,111,99,107,46,97, + 0,0,78,0,0,0,115,38,0,0,0,0,6,8,1,8, + 1,2,2,8,1,20,1,6,1,14,1,14,9,6,247,2, + 9,2,248,8,1,12,1,12,1,44,2,10,1,14,2,8, + 0,122,19,95,77,111,100,117,108,101,76,111,99,107,46,97, 99,113,117,105,114,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, - 36,0,0,0,124,0,106,0,100,1,107,2,114,18,116,1, - 100,2,131,1,130,1,124,0,4,0,106,0,100,3,56,0, - 2,0,95,0,100,0,83,0,41,4,78,114,22,0,0,0, - 114,41,0,0,0,114,37,0,0,0,41,2,114,27,0,0, - 0,114,42,0,0,0,114,46,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,39,0,0,0,132, - 0,0,0,115,6,0,0,0,0,1,10,1,8,1,122,24, + 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, + 142,0,0,0,116,0,160,1,161,0,125,1,124,0,106,2, + 143,108,1,0,124,0,106,3,124,1,107,3,114,34,116,4, + 100,1,131,1,130,1,124,0,106,5,100,2,107,4,115,48, + 74,0,130,1,124,0,4,0,106,5,100,3,56,0,2,0, + 95,5,124,0,106,5,100,2,107,2,114,108,100,0,124,0, + 95,3,124,0,106,6,114,108,124,0,4,0,106,6,100,3, + 56,0,2,0,95,6,124,0,106,7,160,8,161,0,1,0, + 87,0,100,0,4,0,4,0,131,3,1,0,110,16,49,0, + 115,128,48,0,1,0,1,0,1,0,89,0,1,0,100,0, + 83,0,41,4,78,250,31,99,97,110,110,111,116,32,114,101, + 108,101,97,115,101,32,117,110,45,97,99,113,117,105,114,101, + 100,32,108,111,99,107,114,22,0,0,0,114,37,0,0,0, + 41,9,114,23,0,0,0,114,32,0,0,0,114,24,0,0, + 0,114,26,0,0,0,218,12,82,117,110,116,105,109,101,69, + 114,114,111,114,114,27,0,0,0,114,28,0,0,0,114,25, + 0,0,0,114,39,0,0,0,114,40,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,39,0,0, + 0,103,0,0,0,115,22,0,0,0,0,1,8,1,8,1, + 10,1,8,1,14,1,14,1,10,1,6,1,6,1,14,1, + 122,19,95,77,111,100,117,108,101,76,111,99,107,46,114,101, + 108,101,97,115,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,18, + 0,0,0,100,1,160,0,124,0,106,1,116,2,124,0,131, + 1,161,2,83,0,41,2,78,122,23,95,77,111,100,117,108, + 101,76,111,99,107,40,123,33,114,125,41,32,97,116,32,123, + 125,169,3,218,6,102,111,114,109,97,116,114,17,0,0,0, + 218,2,105,100,169,1,114,30,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,8,95,95,114,101, + 112,114,95,95,116,0,0,0,115,2,0,0,0,0,1,122, + 20,95,77,111,100,117,108,101,76,111,99,107,46,95,95,114, + 101,112,114,95,95,78,41,9,114,1,0,0,0,114,0,0, + 0,0,114,2,0,0,0,114,3,0,0,0,114,31,0,0, + 0,114,36,0,0,0,114,38,0,0,0,114,39,0,0,0, + 114,47,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,20,0,0,0,52,0, + 0,0,115,12,0,0,0,8,1,4,5,8,8,8,12,8, + 25,8,13,114,20,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,48,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,83,0,41,11,218,16,95,68,117,109,109,121, + 77,111,100,117,108,101,76,111,99,107,122,86,65,32,115,105, + 109,112,108,101,32,95,77,111,100,117,108,101,76,111,99,107, + 32,101,113,117,105,118,97,108,101,110,116,32,102,111,114,32, + 80,121,116,104,111,110,32,98,117,105,108,100,115,32,119,105, + 116,104,111,117,116,10,32,32,32,32,109,117,108,116,105,45, + 116,104,114,101,97,100,105,110,103,32,115,117,112,112,111,114, + 116,46,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,16,0,0,0, + 124,1,124,0,95,0,100,1,124,0,95,1,100,0,83,0, + 114,21,0,0,0,41,2,114,17,0,0,0,114,27,0,0, + 0,114,29,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,31,0,0,0,124,0,0,0,115,4, + 0,0,0,0,1,6,1,122,25,95,68,117,109,109,121,77, + 111,100,117,108,101,76,111,99,107,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,3,0,0,0,67,0,0,0,115,18,0,0,0, + 124,0,4,0,106,0,100,1,55,0,2,0,95,0,100,2, + 83,0,41,3,78,114,37,0,0,0,84,41,1,114,27,0, + 0,0,114,46,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,38,0,0,0,128,0,0,0,115, + 4,0,0,0,0,1,14,1,122,24,95,68,117,109,109,121, + 77,111,100,117,108,101,76,111,99,107,46,97,99,113,117,105, + 114,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,36,0,0,0, + 124,0,106,0,100,1,107,2,114,18,116,1,100,2,131,1, + 130,1,124,0,4,0,106,0,100,3,56,0,2,0,95,0, + 100,0,83,0,41,4,78,114,22,0,0,0,114,41,0,0, + 0,114,37,0,0,0,41,2,114,27,0,0,0,114,42,0, + 0,0,114,46,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,39,0,0,0,132,0,0,0,115, + 6,0,0,0,0,1,10,1,8,1,122,24,95,68,117,109, + 109,121,77,111,100,117,108,101,76,111,99,107,46,114,101,108, + 101,97,115,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,18,0, + 0,0,100,1,160,0,124,0,106,1,116,2,124,0,131,1, + 161,2,83,0,41,2,78,122,28,95,68,117,109,109,121,77, + 111,100,117,108,101,76,111,99,107,40,123,33,114,125,41,32, + 97,116,32,123,125,114,43,0,0,0,114,46,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,47, + 0,0,0,137,0,0,0,115,2,0,0,0,0,1,122,25, 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, - 46,114,101,108,101,97,115,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,18,0,0,0,100,1,160,0,124,0,106,1,116,2, - 124,0,131,1,161,2,83,0,41,2,78,122,28,95,68,117, - 109,109,121,77,111,100,117,108,101,76,111,99,107,40,123,33, - 114,125,41,32,97,116,32,123,125,114,43,0,0,0,114,46, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,47,0,0,0,137,0,0,0,115,2,0,0,0, - 0,1,122,25,95,68,117,109,109,121,77,111,100,117,108,101, - 76,111,99,107,46,95,95,114,101,112,114,95,95,78,41,8, - 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, - 3,0,0,0,114,31,0,0,0,114,38,0,0,0,114,39, - 0,0,0,114,47,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,48,0,0, - 0,120,0,0,0,115,10,0,0,0,8,1,4,3,8,4, - 8,4,8,5,114,48,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,36,0,0,0,101,0,90,1,100,0,90,2,100, - 1,100,2,132,0,90,3,100,3,100,4,132,0,90,4,100, - 5,100,6,132,0,90,5,100,7,83,0,41,8,218,18,95, - 77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101, - 114,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,16,0,0,0,124, - 1,124,0,95,0,100,0,124,0,95,1,100,0,83,0,114, - 13,0,0,0,41,2,218,5,95,110,97,109,101,218,5,95, - 108,111,99,107,114,29,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,31,0,0,0,143,0,0, - 0,115,4,0,0,0,0,1,6,1,122,27,95,77,111,100, - 117,108,101,76,111,99,107,77,97,110,97,103,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,26,0,0,0,116,0,124,0,106,1,131,1,124,0,95, - 2,124,0,106,2,160,3,161,0,1,0,100,0,83,0,114, - 13,0,0,0,41,4,218,16,95,103,101,116,95,109,111,100, - 117,108,101,95,108,111,99,107,114,50,0,0,0,114,51,0, - 0,0,114,38,0,0,0,114,46,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,9,95,95,101, - 110,116,101,114,95,95,147,0,0,0,115,4,0,0,0,0, - 1,12,1,122,28,95,77,111,100,117,108,101,76,111,99,107, - 77,97,110,97,103,101,114,46,95,95,101,110,116,101,114,95, - 95,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,2,0,0,0,79,0,0,0,115,14,0,0,0,124, - 0,106,0,160,1,161,0,1,0,100,0,83,0,114,13,0, - 0,0,41,2,114,51,0,0,0,114,39,0,0,0,41,3, - 114,30,0,0,0,218,4,97,114,103,115,90,6,107,119,97, - 114,103,115,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,8,95,95,101,120,105,116,95,95,151,0,0,0, - 115,2,0,0,0,0,1,122,27,95,77,111,100,117,108,101, - 76,111,99,107,77,97,110,97,103,101,114,46,95,95,101,120, - 105,116,95,95,78,41,6,114,1,0,0,0,114,0,0,0, - 0,114,2,0,0,0,114,31,0,0,0,114,53,0,0,0, - 114,55,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,49,0,0,0,141,0, - 0,0,115,6,0,0,0,8,2,8,4,8,4,114,49,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,8,0,0,0,67,0,0,0,115,130,0,0,0, - 116,0,160,1,161,0,1,0,122,106,122,14,116,3,124,0, - 25,0,131,0,125,1,87,0,110,24,4,0,116,4,107,10, - 114,48,1,0,1,0,1,0,100,1,125,1,89,0,110,2, - 88,0,124,1,100,1,107,8,114,112,116,5,100,1,107,8, - 114,76,116,6,124,0,131,1,125,1,110,8,116,7,124,0, - 131,1,125,1,124,0,102,1,100,2,100,3,132,1,125,2, - 116,8,160,9,124,1,124,2,161,2,116,3,124,0,60,0, - 87,0,53,0,116,0,160,2,161,0,1,0,88,0,124,1, - 83,0,41,4,122,139,71,101,116,32,111,114,32,99,114,101, - 97,116,101,32,116,104,101,32,109,111,100,117,108,101,32,108, - 111,99,107,32,102,111,114,32,97,32,103,105,118,101,110,32, - 109,111,100,117,108,101,32,110,97,109,101,46,10,10,32,32, - 32,32,65,99,113,117,105,114,101,47,114,101,108,101,97,115, - 101,32,105,110,116,101,114,110,97,108,108,121,32,116,104,101, - 32,103,108,111,98,97,108,32,105,109,112,111,114,116,32,108, - 111,99,107,32,116,111,32,112,114,111,116,101,99,116,10,32, - 32,32,32,95,109,111,100,117,108,101,95,108,111,99,107,115, - 46,78,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,83,0,0,0,115,48,0,0,0, - 116,0,160,1,161,0,1,0,122,24,116,3,160,4,124,1, - 161,1,124,0,107,8,114,30,116,3,124,1,61,0,87,0, - 53,0,116,0,160,2,161,0,1,0,88,0,100,0,83,0, - 114,13,0,0,0,41,5,218,4,95,105,109,112,218,12,97, - 99,113,117,105,114,101,95,108,111,99,107,218,12,114,101,108, - 101,97,115,101,95,108,111,99,107,218,13,95,109,111,100,117, - 108,101,95,108,111,99,107,115,114,34,0,0,0,41,2,218, - 3,114,101,102,114,17,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,218,2,99,98,176,0,0,0, - 115,10,0,0,0,0,1,8,1,2,4,14,1,10,2,122, - 28,95,103,101,116,95,109,111,100,117,108,101,95,108,111,99, - 107,46,60,108,111,99,97,108,115,62,46,99,98,41,10,114, - 56,0,0,0,114,57,0,0,0,114,58,0,0,0,114,59, - 0,0,0,218,8,75,101,121,69,114,114,111,114,114,23,0, - 0,0,114,48,0,0,0,114,20,0,0,0,218,8,95,119, - 101,97,107,114,101,102,114,60,0,0,0,41,3,114,17,0, - 0,0,114,24,0,0,0,114,61,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,52,0,0,0, - 157,0,0,0,115,28,0,0,0,0,6,8,1,2,1,2, - 1,14,1,14,1,10,2,8,1,8,1,10,2,8,2,12, - 11,20,2,10,2,114,52,0,0,0,99,1,0,0,0,0, + 46,95,95,114,101,112,114,95,95,78,41,8,114,1,0,0, + 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, + 114,31,0,0,0,114,38,0,0,0,114,39,0,0,0,114, + 47,0,0,0,114,10,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,48,0,0,0,120,0,0, + 0,115,10,0,0,0,8,1,4,3,8,4,8,4,8,5, + 114,48,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,36, + 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132, + 0,90,3,100,3,100,4,132,0,90,4,100,5,100,6,132, + 0,90,5,100,7,83,0,41,8,218,18,95,77,111,100,117, + 108,101,76,111,99,107,77,97,110,97,103,101,114,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,16,0,0,0,124,1,124,0,95, + 0,100,0,124,0,95,1,100,0,83,0,114,13,0,0,0, + 41,2,218,5,95,110,97,109,101,218,5,95,108,111,99,107, + 114,29,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,31,0,0,0,143,0,0,0,115,4,0, + 0,0,0,1,6,1,122,27,95,77,111,100,117,108,101,76, + 111,99,107,77,97,110,97,103,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,26,0,0, + 0,116,0,124,0,106,1,131,1,124,0,95,2,124,0,106, + 2,160,3,161,0,1,0,100,0,83,0,114,13,0,0,0, + 41,4,218,16,95,103,101,116,95,109,111,100,117,108,101,95, + 108,111,99,107,114,50,0,0,0,114,51,0,0,0,114,38, + 0,0,0,114,46,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,9,95,95,101,110,116,101,114, + 95,95,147,0,0,0,115,4,0,0,0,0,1,12,1,122, + 28,95,77,111,100,117,108,101,76,111,99,107,77,97,110,97, + 103,101,114,46,95,95,101,110,116,101,114,95,95,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0, + 0,0,79,0,0,0,115,14,0,0,0,124,0,106,0,160, + 1,161,0,1,0,100,0,83,0,114,13,0,0,0,41,2, + 114,51,0,0,0,114,39,0,0,0,41,3,114,30,0,0, + 0,218,4,97,114,103,115,90,6,107,119,97,114,103,115,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, + 95,95,101,120,105,116,95,95,151,0,0,0,115,2,0,0, + 0,0,1,122,27,95,77,111,100,117,108,101,76,111,99,107, + 77,97,110,97,103,101,114,46,95,95,101,120,105,116,95,95, + 78,41,6,114,1,0,0,0,114,0,0,0,0,114,2,0, + 0,0,114,31,0,0,0,114,53,0,0,0,114,55,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,49,0,0,0,141,0,0,0,115,6, + 0,0,0,8,2,8,4,8,4,114,49,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8, + 0,0,0,67,0,0,0,115,138,0,0,0,116,0,160,1, + 161,0,1,0,122,114,122,14,116,2,124,0,25,0,131,0, + 125,1,87,0,110,24,4,0,116,3,107,10,114,48,1,0, + 1,0,1,0,100,1,125,1,89,0,110,2,48,0,124,1, + 100,1,107,8,114,112,116,4,100,1,107,8,114,76,116,5, + 124,0,131,1,125,1,110,8,116,6,124,0,131,1,125,1, + 124,0,102,1,100,2,100,3,132,1,125,2,116,7,160,8, + 124,1,124,2,161,2,116,2,124,0,60,0,87,0,116,0, + 160,9,161,0,1,0,110,10,116,0,160,9,161,0,1,0, + 48,0,124,1,83,0,41,4,122,139,71,101,116,32,111,114, + 32,99,114,101,97,116,101,32,116,104,101,32,109,111,100,117, + 108,101,32,108,111,99,107,32,102,111,114,32,97,32,103,105, + 118,101,110,32,109,111,100,117,108,101,32,110,97,109,101,46, + 10,10,32,32,32,32,65,99,113,117,105,114,101,47,114,101, + 108,101,97,115,101,32,105,110,116,101,114,110,97,108,108,121, + 32,116,104,101,32,103,108,111,98,97,108,32,105,109,112,111, + 114,116,32,108,111,99,107,32,116,111,32,112,114,111,116,101, + 99,116,10,32,32,32,32,95,109,111,100,117,108,101,95,108, + 111,99,107,115,46,78,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,8,0,0,0,83,0,0,0,115, + 56,0,0,0,116,0,160,1,161,0,1,0,122,32,116,2, + 160,3,124,1,161,1,124,0,107,8,114,30,116,2,124,1, + 61,0,87,0,116,0,160,4,161,0,1,0,110,10,116,0, + 160,4,161,0,1,0,48,0,100,0,83,0,114,13,0,0, + 0,41,5,218,4,95,105,109,112,218,12,97,99,113,117,105, + 114,101,95,108,111,99,107,218,13,95,109,111,100,117,108,101, + 95,108,111,99,107,115,114,34,0,0,0,218,12,114,101,108, + 101,97,115,101,95,108,111,99,107,41,2,218,3,114,101,102, + 114,17,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,2,99,98,176,0,0,0,115,12,0,0, + 0,0,1,8,1,2,4,14,1,8,2,10,0,122,28,95, + 103,101,116,95,109,111,100,117,108,101,95,108,111,99,107,46, + 60,108,111,99,97,108,115,62,46,99,98,41,10,114,56,0, + 0,0,114,57,0,0,0,114,58,0,0,0,218,8,75,101, + 121,69,114,114,111,114,114,23,0,0,0,114,48,0,0,0, + 114,20,0,0,0,218,8,95,119,101,97,107,114,101,102,114, + 60,0,0,0,114,59,0,0,0,41,3,114,17,0,0,0, + 114,24,0,0,0,114,61,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,52,0,0,0,157,0, + 0,0,115,30,0,0,0,0,6,8,1,2,1,2,1,14, + 1,14,1,10,2,8,1,8,1,10,2,8,2,12,11,18, + 2,10,0,10,2,114,52,0,0,0,99,1,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,67, 0,0,0,115,54,0,0,0,116,0,124,0,131,1,125,1, 122,12,124,1,160,1,161,0,1,0,87,0,110,20,4,0, 116,2,107,10,114,40,1,0,1,0,1,0,89,0,110,10, - 88,0,124,1,160,3,161,0,1,0,100,1,83,0,41,2, + 48,0,124,1,160,3,161,0,1,0,100,1,83,0,41,2, 122,189,65,99,113,117,105,114,101,115,32,116,104,101,110,32, 114,101,108,101,97,115,101,115,32,116,104,101,32,109,111,100, 117,108,101,32,108,111,99,107,32,102,111,114,32,97,32,103, @@ -493,17 +498,17 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,115,226,0,0,0,116,0,124,0,100,1,100,0,131, 3,125,1,116,1,124,1,100,2,131,2,114,56,122,12,124, 1,160,2,124,0,161,1,87,0,83,0,4,0,116,3,107, - 10,114,54,1,0,1,0,1,0,89,0,110,2,88,0,122, + 10,114,54,1,0,1,0,1,0,89,0,110,2,48,0,122, 10,124,0,106,4,125,2,87,0,110,20,4,0,116,5,107, - 10,114,86,1,0,1,0,1,0,89,0,110,18,88,0,124, + 10,114,86,1,0,1,0,1,0,89,0,110,18,48,0,124, 2,100,0,107,9,114,104,116,6,124,2,131,1,83,0,122, 10,124,0,106,7,125,3,87,0,110,24,4,0,116,5,107, 10,114,138,1,0,1,0,1,0,100,3,125,3,89,0,110, - 2,88,0,122,10,124,0,106,8,125,4,87,0,110,58,4, + 2,48,0,122,10,124,0,106,8,125,4,87,0,110,58,4, 0,116,5,107,10,114,208,1,0,1,0,1,0,124,1,100, 0,107,8,114,188,100,4,160,9,124,3,161,1,6,0,89, 0,83,0,100,5,160,9,124,3,124,1,161,2,6,0,89, - 0,83,0,89,0,110,14,88,0,100,6,160,9,124,3,124, + 0,83,0,89,0,110,14,48,0,100,6,160,9,124,3,124, 4,161,2,83,0,100,0,83,0,41,7,78,218,10,95,95, 108,111,97,100,101,114,95,95,218,11,109,111,100,117,108,101, 95,114,101,112,114,250,1,63,250,13,60,109,111,100,117,108, @@ -676,7 +681,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76, 124,0,106,5,124,1,106,5,107,2,87,0,83,0,4,0, 116,6,107,10,114,102,1,0,1,0,1,0,116,7,6,0, - 89,0,83,0,88,0,100,0,83,0,114,13,0,0,0,41, + 89,0,83,0,48,0,100,0,83,0,114,13,0,0,0,41, 8,114,115,0,0,0,114,17,0,0,0,114,108,0,0,0, 114,112,0,0,0,218,6,99,97,99,104,101,100,218,12,104, 97,115,95,108,111,99,97,116,105,111,110,114,105,0,0,0, @@ -753,7 +758,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,0,124,1,100,5,131,2,114,134,122,14,124,1,160,4, 124,0,161,1,125,3,87,0,113,138,4,0,116,5,107,10, 114,130,1,0,1,0,1,0,100,2,125,3,89,0,113,138, - 88,0,110,4,100,6,125,3,116,6,124,0,124,1,124,2, + 48,0,110,4,100,6,125,3,116,6,124,0,124,1,124,2, 124,3,100,7,141,4,83,0,41,8,122,53,82,101,116,117, 114,110,32,97,32,109,111,100,117,108,101,32,115,112,101,99, 32,98,97,115,101,100,32,111,110,32,118,97,114,105,111,117, @@ -774,22 +779,22 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 99,3,0,0,0,0,0,0,0,0,0,0,0,8,0,0, 0,8,0,0,0,67,0,0,0,115,56,1,0,0,122,10, 124,0,106,0,125,3,87,0,110,20,4,0,116,1,107,10, - 114,30,1,0,1,0,1,0,89,0,110,14,88,0,124,3, + 114,30,1,0,1,0,1,0,89,0,110,14,48,0,124,3, 100,0,107,9,114,44,124,3,83,0,124,0,106,2,125,4, 124,1,100,0,107,8,114,90,122,10,124,0,106,3,125,1, 87,0,110,20,4,0,116,1,107,10,114,88,1,0,1,0, - 1,0,89,0,110,2,88,0,122,10,124,0,106,4,125,5, + 1,0,89,0,110,2,48,0,122,10,124,0,106,4,125,5, 87,0,110,24,4,0,116,1,107,10,114,124,1,0,1,0, - 1,0,100,0,125,5,89,0,110,2,88,0,124,2,100,0, + 1,0,100,0,125,5,89,0,110,2,48,0,124,2,100,0, 107,8,114,184,124,5,100,0,107,8,114,180,122,10,124,1, 106,5,125,2,87,0,113,184,4,0,116,1,107,10,114,176, - 1,0,1,0,1,0,100,0,125,2,89,0,113,184,88,0, + 1,0,1,0,1,0,100,0,125,2,89,0,113,184,48,0, 110,4,124,5,125,2,122,10,124,0,106,6,125,6,87,0, 110,24,4,0,116,1,107,10,114,218,1,0,1,0,1,0, - 100,0,125,6,89,0,110,2,88,0,122,14,116,7,124,0, + 100,0,125,6,89,0,110,2,48,0,122,14,116,7,124,0, 106,8,131,1,125,7,87,0,110,26,4,0,116,1,107,10, 144,1,114,4,1,0,1,0,1,0,100,0,125,7,89,0, - 110,2,88,0,116,9,124,4,124,1,124,2,100,1,141,3, + 110,2,48,0,116,9,124,4,124,1,124,2,100,1,141,3, 125,3,124,5,100,0,107,8,144,1,114,34,100,2,110,2, 100,3,124,3,95,10,124,6,124,3,95,11,124,7,124,3, 95,12,124,3,83,0,41,4,78,169,1,114,112,0,0,0, @@ -814,7 +819,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,115,226,1,0,0,124,2,115,20,116,0,124,1, 100,1,100,0,131,3,100,0,107,8,114,54,122,12,124,0, 106,1,124,1,95,2,87,0,110,20,4,0,116,3,107,10, - 114,52,1,0,1,0,1,0,89,0,110,2,88,0,124,2, + 114,52,1,0,1,0,1,0,89,0,110,2,48,0,124,2, 115,74,116,0,124,1,100,2,100,0,131,3,100,0,107,8, 114,178,124,0,106,4,125,3,124,3,100,0,107,8,114,146, 124,0,106,5,100,0,107,9,114,146,116,6,100,0,107,8, @@ -822,26 +827,26 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 124,4,161,1,125,3,124,0,106,5,124,3,95,10,124,3, 124,0,95,4,100,0,124,1,95,11,122,10,124,3,124,1, 95,12,87,0,110,20,4,0,116,3,107,10,114,176,1,0, - 1,0,1,0,89,0,110,2,88,0,124,2,115,198,116,0, + 1,0,1,0,89,0,110,2,48,0,124,2,115,198,116,0, 124,1,100,3,100,0,131,3,100,0,107,8,114,232,122,12, 124,0,106,13,124,1,95,14,87,0,110,20,4,0,116,3, - 107,10,114,230,1,0,1,0,1,0,89,0,110,2,88,0, + 107,10,114,230,1,0,1,0,1,0,89,0,110,2,48,0, 122,10,124,0,124,1,95,15,87,0,110,22,4,0,116,3, 107,10,144,1,114,8,1,0,1,0,1,0,89,0,110,2, - 88,0,124,2,144,1,115,34,116,0,124,1,100,4,100,0, + 48,0,124,2,144,1,115,34,116,0,124,1,100,4,100,0, 131,3,100,0,107,8,144,1,114,82,124,0,106,5,100,0, 107,9,144,1,114,82,122,12,124,0,106,5,124,1,95,16, 87,0,110,22,4,0,116,3,107,10,144,1,114,80,1,0, - 1,0,1,0,89,0,110,2,88,0,124,0,106,17,144,1, + 1,0,1,0,89,0,110,2,48,0,124,0,106,17,144,1, 114,222,124,2,144,1,115,114,116,0,124,1,100,5,100,0, 131,3,100,0,107,8,144,1,114,150,122,12,124,0,106,18, 124,1,95,11,87,0,110,22,4,0,116,3,107,10,144,1, - 114,148,1,0,1,0,1,0,89,0,110,2,88,0,124,2, + 114,148,1,0,1,0,1,0,89,0,110,2,48,0,124,2, 144,1,115,174,116,0,124,1,100,6,100,0,131,3,100,0, 107,8,144,1,114,222,124,0,106,19,100,0,107,9,144,1, 114,222,122,12,124,0,106,19,124,1,95,20,87,0,110,22, 4,0,116,3,107,10,144,1,114,220,1,0,1,0,1,0, - 89,0,110,2,88,0,124,1,83,0,41,7,78,114,1,0, + 89,0,110,2,48,0,124,1,83,0,41,7,78,114,1,0, 0,0,114,97,0,0,0,218,11,95,95,112,97,99,107,97, 103,101,95,95,114,140,0,0,0,114,107,0,0,0,114,138, 0,0,0,41,21,114,6,0,0,0,114,17,0,0,0,114, @@ -906,886 +911,894 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,106,0,0,0,54,2,0,0,115,16,0,0,0,0,3, 20,1,10,1,10,1,10,2,16,2,6,1,14,2,114,106, 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,10,0,0,0,67,0,0,0,115,204,0,0, - 0,124,0,106,0,125,2,116,1,124,2,131,1,143,180,1, + 4,0,0,0,10,0,0,0,67,0,0,0,115,250,0,0, + 0,124,0,106,0,125,2,116,1,124,2,131,1,143,216,1, 0,116,2,106,3,160,4,124,2,161,1,124,1,107,9,114, 54,100,1,160,5,124,2,161,1,125,3,116,6,124,3,124, - 2,100,2,141,2,130,1,122,106,124,0,106,8,100,3,107, - 8,114,106,124,0,106,9,100,3,107,8,114,90,116,6,100, - 4,124,0,106,0,100,2,141,2,130,1,116,10,124,0,124, - 1,100,5,100,6,141,3,1,0,110,52,116,10,124,0,124, - 1,100,5,100,6,141,3,1,0,116,11,124,0,106,8,100, - 7,131,2,115,146,124,0,106,8,160,12,124,2,161,1,1, - 0,110,12,124,0,106,8,160,13,124,1,161,1,1,0,87, - 0,53,0,116,2,106,3,160,7,124,0,106,0,161,1,125, - 1,124,1,116,2,106,3,124,0,106,0,60,0,88,0,87, - 0,53,0,81,0,82,0,88,0,124,1,83,0,41,8,122, - 70,69,120,101,99,117,116,101,32,116,104,101,32,115,112,101, - 99,39,115,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,117,108,101,32,105,110,32,97,110,32,101,120,105,115,116, - 105,110,103,32,109,111,100,117,108,101,39,115,32,110,97,109, - 101,115,112,97,99,101,46,122,30,109,111,100,117,108,101,32, - 123,33,114,125,32,110,111,116,32,105,110,32,115,121,115,46, - 109,111,100,117,108,101,115,114,16,0,0,0,78,250,14,109, - 105,115,115,105,110,103,32,108,111,97,100,101,114,84,114,142, - 0,0,0,114,149,0,0,0,41,14,114,17,0,0,0,114, - 49,0,0,0,114,15,0,0,0,114,91,0,0,0,114,34, - 0,0,0,114,44,0,0,0,114,78,0,0,0,218,3,112, - 111,112,114,108,0,0,0,114,115,0,0,0,114,147,0,0, - 0,114,4,0,0,0,218,11,108,111,97,100,95,109,111,100, - 117,108,101,114,149,0,0,0,41,4,114,94,0,0,0,114, - 95,0,0,0,114,17,0,0,0,218,3,109,115,103,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,92,0, - 0,0,71,2,0,0,115,34,0,0,0,0,2,6,1,10, - 1,16,1,10,1,12,1,2,1,10,1,10,1,14,2,16, - 2,14,1,12,4,14,2,16,4,14,1,24,1,114,92,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,26,1,0,0, - 122,18,124,0,106,0,160,1,124,0,106,2,161,1,1,0, - 87,0,110,52,1,0,1,0,1,0,124,0,106,2,116,3, - 106,4,107,6,114,64,116,3,106,4,160,5,124,0,106,2, - 161,1,125,1,124,1,116,3,106,4,124,0,106,2,60,0, - 130,0,89,0,110,2,88,0,116,3,106,4,160,5,124,0, + 2,100,2,141,2,130,1,122,132,124,0,106,7,100,3,107, + 8,114,106,124,0,106,8,100,3,107,8,114,90,116,6,100, + 4,124,0,106,0,100,2,141,2,130,1,116,9,124,0,124, + 1,100,5,100,6,141,3,1,0,110,52,116,9,124,0,124, + 1,100,5,100,6,141,3,1,0,116,10,124,0,106,7,100, + 7,131,2,115,146,124,0,106,7,160,11,124,2,161,1,1, + 0,110,12,124,0,106,7,160,12,124,1,161,1,1,0,87, + 0,116,2,106,3,160,13,124,0,106,0,161,1,125,1,124, + 1,116,2,106,3,124,0,106,0,60,0,110,28,116,2,106, + 3,160,13,124,0,106,0,161,1,125,1,124,1,116,2,106, + 3,124,0,106,0,60,0,48,0,87,0,100,3,4,0,4, + 0,131,3,1,0,110,16,49,0,115,236,48,0,1,0,1, + 0,1,0,89,0,1,0,124,1,83,0,41,8,122,70,69, + 120,101,99,117,116,101,32,116,104,101,32,115,112,101,99,39, + 115,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, + 108,101,32,105,110,32,97,110,32,101,120,105,115,116,105,110, + 103,32,109,111,100,117,108,101,39,115,32,110,97,109,101,115, + 112,97,99,101,46,122,30,109,111,100,117,108,101,32,123,33, + 114,125,32,110,111,116,32,105,110,32,115,121,115,46,109,111, + 100,117,108,101,115,114,16,0,0,0,78,250,14,109,105,115, + 115,105,110,103,32,108,111,97,100,101,114,84,114,142,0,0, + 0,114,149,0,0,0,41,14,114,17,0,0,0,114,49,0, + 0,0,114,15,0,0,0,114,91,0,0,0,114,34,0,0, + 0,114,44,0,0,0,114,78,0,0,0,114,108,0,0,0, + 114,115,0,0,0,114,147,0,0,0,114,4,0,0,0,218, + 11,108,111,97,100,95,109,111,100,117,108,101,114,149,0,0, + 0,218,3,112,111,112,41,4,114,94,0,0,0,114,95,0, + 0,0,114,17,0,0,0,218,3,109,115,103,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,92,0,0,0, + 71,2,0,0,115,38,0,0,0,0,2,6,1,10,1,16, + 1,10,1,12,1,2,1,10,1,10,1,14,2,16,2,14, + 1,12,4,14,2,14,4,14,1,14,255,14,1,44,1,114, + 92,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,8,0,0,0,67,0,0,0,115,26,1, + 0,0,122,18,124,0,106,0,160,1,124,0,106,2,161,1, + 1,0,87,0,110,52,1,0,1,0,1,0,124,0,106,2, + 116,3,106,4,107,6,114,64,116,3,106,4,160,5,124,0, 106,2,161,1,125,1,124,1,116,3,106,4,124,0,106,2, - 60,0,116,6,124,1,100,1,100,0,131,3,100,0,107,8, - 114,148,122,12,124,0,106,0,124,1,95,7,87,0,110,20, - 4,0,116,8,107,10,114,146,1,0,1,0,1,0,89,0, - 110,2,88,0,116,6,124,1,100,2,100,0,131,3,100,0, - 107,8,114,226,122,40,124,1,106,9,124,1,95,10,116,11, - 124,1,100,3,131,2,115,202,124,0,106,2,160,12,100,4, - 161,1,100,5,25,0,124,1,95,10,87,0,110,20,4,0, - 116,8,107,10,114,224,1,0,1,0,1,0,89,0,110,2, - 88,0,116,6,124,1,100,6,100,0,131,3,100,0,107,8, - 144,1,114,22,122,10,124,0,124,1,95,13,87,0,110,22, - 4,0,116,8,107,10,144,1,114,20,1,0,1,0,1,0, - 89,0,110,2,88,0,124,1,83,0,41,7,78,114,97,0, - 0,0,114,144,0,0,0,114,140,0,0,0,114,127,0,0, - 0,114,22,0,0,0,114,104,0,0,0,41,14,114,108,0, - 0,0,114,155,0,0,0,114,17,0,0,0,114,15,0,0, - 0,114,91,0,0,0,114,154,0,0,0,114,6,0,0,0, - 114,97,0,0,0,114,105,0,0,0,114,1,0,0,0,114, - 144,0,0,0,114,4,0,0,0,114,128,0,0,0,114,104, - 0,0,0,114,150,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,25,95,108,111,97,100,95,98, - 97,99,107,119,97,114,100,95,99,111,109,112,97,116,105,98, - 108,101,101,2,0,0,115,54,0,0,0,0,4,2,1,18, - 1,6,1,12,1,14,1,12,1,8,3,14,1,12,1,16, - 1,2,1,12,1,14,1,6,1,16,1,2,4,8,1,10, - 1,22,1,14,1,6,1,18,1,2,1,10,1,16,1,6, - 1,114,157,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,11,0,0,0,67,0,0,0,115, - 220,0,0,0,124,0,106,0,100,0,107,9,114,30,116,1, - 124,0,106,0,100,1,131,2,115,30,116,2,124,0,131,1, - 83,0,116,3,124,0,131,1,125,1,100,2,124,0,95,4, - 122,162,124,1,116,5,106,6,124,0,106,7,60,0,122,52, - 124,0,106,0,100,0,107,8,114,96,124,0,106,8,100,0, - 107,8,114,108,116,9,100,4,124,0,106,7,100,5,141,2, - 130,1,110,12,124,0,106,0,160,10,124,1,161,1,1,0, - 87,0,110,50,1,0,1,0,1,0,122,14,116,5,106,6, - 124,0,106,7,61,0,87,0,110,20,4,0,116,11,107,10, - 114,152,1,0,1,0,1,0,89,0,110,2,88,0,130,0, - 89,0,110,2,88,0,116,5,106,6,160,12,124,0,106,7, - 161,1,125,1,124,1,116,5,106,6,124,0,106,7,60,0, - 116,13,100,6,124,0,106,7,124,0,106,0,131,3,1,0, - 87,0,53,0,100,3,124,0,95,4,88,0,124,1,83,0, - 41,7,78,114,149,0,0,0,84,70,114,153,0,0,0,114, - 16,0,0,0,122,18,105,109,112,111,114,116,32,123,33,114, - 125,32,35,32,123,33,114,125,41,14,114,108,0,0,0,114, - 4,0,0,0,114,157,0,0,0,114,151,0,0,0,90,13, - 95,105,110,105,116,105,97,108,105,122,105,110,103,114,15,0, - 0,0,114,91,0,0,0,114,17,0,0,0,114,115,0,0, - 0,114,78,0,0,0,114,149,0,0,0,114,62,0,0,0, - 114,154,0,0,0,114,75,0,0,0,114,150,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,14, - 95,108,111,97,100,95,117,110,108,111,99,107,101,100,138,2, - 0,0,115,46,0,0,0,0,2,10,2,12,1,8,2,8, - 5,6,1,2,1,12,1,2,1,10,1,10,1,16,3,16, - 1,6,1,2,1,14,1,14,1,6,1,8,5,14,1,12, - 1,20,2,8,2,114,158,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,67, - 0,0,0,115,42,0,0,0,116,0,124,0,106,1,131,1, - 143,22,1,0,116,2,124,0,131,1,87,0,2,0,53,0, - 81,0,82,0,163,0,83,0,81,0,82,0,88,0,100,1, - 83,0,41,2,122,191,82,101,116,117,114,110,32,97,32,110, - 101,119,32,109,111,100,117,108,101,32,111,98,106,101,99,116, - 44,32,108,111,97,100,101,100,32,98,121,32,116,104,101,32, - 115,112,101,99,39,115,32,108,111,97,100,101,114,46,10,10, - 32,32,32,32,84,104,101,32,109,111,100,117,108,101,32,105, - 115,32,110,111,116,32,97,100,100,101,100,32,116,111,32,105, - 116,115,32,112,97,114,101,110,116,46,10,10,32,32,32,32, - 73,102,32,97,32,109,111,100,117,108,101,32,105,115,32,97, - 108,114,101,97,100,121,32,105,110,32,115,121,115,46,109,111, - 100,117,108,101,115,44,32,116,104,97,116,32,101,120,105,115, - 116,105,110,103,32,109,111,100,117,108,101,32,103,101,116,115, - 10,32,32,32,32,99,108,111,98,98,101,114,101,100,46,10, - 10,32,32,32,32,78,41,3,114,49,0,0,0,114,17,0, - 0,0,114,158,0,0,0,41,1,114,94,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,93,0, - 0,0,180,2,0,0,115,4,0,0,0,0,9,12,1,114, - 93,0,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,140,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 90,4,101,5,100,3,100,4,132,0,131,1,90,6,101,7, - 100,20,100,6,100,7,132,1,131,1,90,8,101,7,100,21, - 100,8,100,9,132,1,131,1,90,9,101,7,100,10,100,11, - 132,0,131,1,90,10,101,7,100,12,100,13,132,0,131,1, - 90,11,101,7,101,12,100,14,100,15,132,0,131,1,131,1, - 90,13,101,7,101,12,100,16,100,17,132,0,131,1,131,1, - 90,14,101,7,101,12,100,18,100,19,132,0,131,1,131,1, - 90,15,101,7,101,16,131,1,90,17,100,5,83,0,41,22, - 218,15,66,117,105,108,116,105,110,73,109,112,111,114,116,101, - 114,122,144,77,101,116,97,32,112,97,116,104,32,105,109,112, - 111,114,116,32,102,111,114,32,98,117,105,108,116,45,105,110, - 32,109,111,100,117,108,101,115,46,10,10,32,32,32,32,65, - 108,108,32,109,101,116,104,111,100,115,32,97,114,101,32,101, - 105,116,104,101,114,32,99,108,97,115,115,32,111,114,32,115, - 116,97,116,105,99,32,109,101,116,104,111,100,115,32,116,111, - 32,97,118,111,105,100,32,116,104,101,32,110,101,101,100,32, - 116,111,10,32,32,32,32,105,110,115,116,97,110,116,105,97, - 116,101,32,116,104,101,32,99,108,97,115,115,46,10,10,32, - 32,32,32,122,8,98,117,105,108,116,45,105,110,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,22,0,0,0,100,1,124,0,106, - 0,155,2,100,2,116,1,106,2,155,0,100,3,157,5,83, - 0,41,4,250,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,8,60,109,111,100,117,108, - 101,32,122,2,32,40,122,2,41,62,41,3,114,1,0,0, - 0,114,159,0,0,0,114,137,0,0,0,41,1,114,95,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,98,0,0,0,206,2,0,0,115,2,0,0,0,0, - 7,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,109,111,100,117,108,101,95,114,101,112,114,78,99, - 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, - 5,0,0,0,67,0,0,0,115,46,0,0,0,124,2,100, - 0,107,9,114,12,100,0,83,0,116,0,160,1,124,1,161, - 1,114,38,116,2,124,1,124,0,124,0,106,3,100,1,141, - 3,83,0,100,0,83,0,100,0,83,0,169,2,78,114,136, - 0,0,0,41,4,114,56,0,0,0,90,10,105,115,95,98, - 117,105,108,116,105,110,114,90,0,0,0,114,137,0,0,0, - 169,4,218,3,99,108,115,114,80,0,0,0,218,4,112,97, - 116,104,218,6,116,97,114,103,101,116,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,9,102,105,110,100,95, - 115,112,101,99,215,2,0,0,115,10,0,0,0,0,2,8, - 1,4,1,10,1,16,2,122,25,66,117,105,108,116,105,110, - 73,109,112,111,114,116,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, - 107,9,114,26,124,3,106,1,83,0,100,1,83,0,41,2, - 122,175,70,105,110,100,32,116,104,101,32,98,117,105,108,116, - 45,105,110,32,109,111,100,117,108,101,46,10,10,32,32,32, - 32,32,32,32,32,73,102,32,39,112,97,116,104,39,32,105, - 115,32,101,118,101,114,32,115,112,101,99,105,102,105,101,100, - 32,116,104,101,110,32,116,104,101,32,115,101,97,114,99,104, - 32,105,115,32,99,111,110,115,105,100,101,114,101,100,32,97, - 32,102,97,105,108,117,114,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,41,2,114,166,0,0,0,114,108,0,0,0,41,4, - 114,163,0,0,0,114,80,0,0,0,114,164,0,0,0,114, + 60,0,130,0,89,0,110,2,48,0,116,3,106,4,160,5, + 124,0,106,2,161,1,125,1,124,1,116,3,106,4,124,0, + 106,2,60,0,116,6,124,1,100,1,100,0,131,3,100,0, + 107,8,114,148,122,12,124,0,106,0,124,1,95,7,87,0, + 110,20,4,0,116,8,107,10,114,146,1,0,1,0,1,0, + 89,0,110,2,48,0,116,6,124,1,100,2,100,0,131,3, + 100,0,107,8,114,226,122,40,124,1,106,9,124,1,95,10, + 116,11,124,1,100,3,131,2,115,202,124,0,106,2,160,12, + 100,4,161,1,100,5,25,0,124,1,95,10,87,0,110,20, + 4,0,116,8,107,10,114,224,1,0,1,0,1,0,89,0, + 110,2,48,0,116,6,124,1,100,6,100,0,131,3,100,0, + 107,8,144,1,114,22,122,10,124,0,124,1,95,13,87,0, + 110,22,4,0,116,8,107,10,144,1,114,20,1,0,1,0, + 1,0,89,0,110,2,48,0,124,1,83,0,41,7,78,114, + 97,0,0,0,114,144,0,0,0,114,140,0,0,0,114,127, + 0,0,0,114,22,0,0,0,114,104,0,0,0,41,14,114, + 108,0,0,0,114,154,0,0,0,114,17,0,0,0,114,15, + 0,0,0,114,91,0,0,0,114,155,0,0,0,114,6,0, + 0,0,114,97,0,0,0,114,105,0,0,0,114,1,0,0, + 0,114,144,0,0,0,114,4,0,0,0,114,128,0,0,0, + 114,104,0,0,0,114,150,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,25,95,108,111,97,100, + 95,98,97,99,107,119,97,114,100,95,99,111,109,112,97,116, + 105,98,108,101,101,2,0,0,115,54,0,0,0,0,4,2, + 1,18,1,6,1,12,1,14,1,12,1,8,3,14,1,12, + 1,16,1,2,1,12,1,14,1,6,1,16,1,2,4,8, + 1,10,1,22,1,14,1,6,1,18,1,2,1,10,1,16, + 1,6,1,114,157,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,11,0,0,0,67,0,0, + 0,115,226,0,0,0,124,0,106,0,100,0,107,9,114,30, + 116,1,124,0,106,0,100,1,131,2,115,30,116,2,124,0, + 131,1,83,0,116,3,124,0,131,1,125,1,100,2,124,0, + 95,4,122,168,124,1,116,5,106,6,124,0,106,7,60,0, + 122,52,124,0,106,0,100,0,107,8,114,96,124,0,106,8, + 100,0,107,8,114,108,116,9,100,3,124,0,106,7,100,4, + 141,2,130,1,110,12,124,0,106,0,160,10,124,1,161,1, + 1,0,87,0,110,50,1,0,1,0,1,0,122,14,116,5, + 106,6,124,0,106,7,61,0,87,0,110,20,4,0,116,11, + 107,10,114,152,1,0,1,0,1,0,89,0,110,2,48,0, + 130,0,89,0,110,2,48,0,116,5,106,6,160,12,124,0, + 106,7,161,1,125,1,124,1,116,5,106,6,124,0,106,7, + 60,0,116,13,100,5,124,0,106,7,124,0,106,0,131,3, + 1,0,87,0,100,6,124,0,95,4,110,8,100,6,124,0, + 95,4,48,0,124,1,83,0,41,7,78,114,149,0,0,0, + 84,114,153,0,0,0,114,16,0,0,0,122,18,105,109,112, + 111,114,116,32,123,33,114,125,32,35,32,123,33,114,125,70, + 41,14,114,108,0,0,0,114,4,0,0,0,114,157,0,0, + 0,114,151,0,0,0,90,13,95,105,110,105,116,105,97,108, + 105,122,105,110,103,114,15,0,0,0,114,91,0,0,0,114, + 17,0,0,0,114,115,0,0,0,114,78,0,0,0,114,149, + 0,0,0,114,62,0,0,0,114,155,0,0,0,114,75,0, + 0,0,114,150,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,14,95,108,111,97,100,95,117,110, + 108,111,99,107,101,100,138,2,0,0,115,48,0,0,0,0, + 2,10,2,12,1,8,2,8,5,6,1,2,1,12,1,2, + 1,10,1,10,1,16,3,16,1,6,1,2,1,14,1,14, + 1,6,1,8,5,14,1,12,1,18,2,8,0,8,2,114, + 158,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,8,0,0,0,67,0,0,0,115,54,0, + 0,0,116,0,124,0,106,1,131,1,143,24,1,0,116,2, + 124,0,131,1,87,0,2,0,100,1,4,0,4,0,131,3, + 1,0,83,0,49,0,115,40,48,0,1,0,1,0,1,0, + 89,0,1,0,100,1,83,0,41,2,122,191,82,101,116,117, + 114,110,32,97,32,110,101,119,32,109,111,100,117,108,101,32, + 111,98,106,101,99,116,44,32,108,111,97,100,101,100,32,98, + 121,32,116,104,101,32,115,112,101,99,39,115,32,108,111,97, + 100,101,114,46,10,10,32,32,32,32,84,104,101,32,109,111, + 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, + 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, + 10,10,32,32,32,32,73,102,32,97,32,109,111,100,117,108, + 101,32,105,115,32,97,108,114,101,97,100,121,32,105,110,32, + 115,121,115,46,109,111,100,117,108,101,115,44,32,116,104,97, + 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, + 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, + 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,49, + 0,0,0,114,17,0,0,0,114,158,0,0,0,41,1,114, 94,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, - 224,2,0,0,115,4,0,0,0,0,9,12,1,122,27,66, + 0,0,0,114,93,0,0,0,180,2,0,0,115,4,0,0, + 0,0,9,12,1,114,93,0,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,140,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,90,4,101,5,100,3,100,4,132,0, + 131,1,90,6,101,7,100,20,100,6,100,7,132,1,131,1, + 90,8,101,7,100,21,100,8,100,9,132,1,131,1,90,9, + 101,7,100,10,100,11,132,0,131,1,90,10,101,7,100,12, + 100,13,132,0,131,1,90,11,101,7,101,12,100,14,100,15, + 132,0,131,1,131,1,90,13,101,7,101,12,100,16,100,17, + 132,0,131,1,131,1,90,14,101,7,101,12,100,18,100,19, + 132,0,131,1,131,1,90,15,101,7,101,16,131,1,90,17, + 100,5,83,0,41,22,218,15,66,117,105,108,116,105,110,73, + 109,112,111,114,116,101,114,122,144,77,101,116,97,32,112,97, + 116,104,32,105,109,112,111,114,116,32,102,111,114,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,115,46,10, + 10,32,32,32,32,65,108,108,32,109,101,116,104,111,100,115, + 32,97,114,101,32,101,105,116,104,101,114,32,99,108,97,115, + 115,32,111,114,32,115,116,97,116,105,99,32,109,101,116,104, + 111,100,115,32,116,111,32,97,118,111,105,100,32,116,104,101, + 32,110,101,101,100,32,116,111,10,32,32,32,32,105,110,115, + 116,97,110,116,105,97,116,101,32,116,104,101,32,99,108,97, + 115,115,46,10,10,32,32,32,32,122,8,98,117,105,108,116, + 45,105,110,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,22,0,0, + 0,100,1,124,0,106,0,155,2,100,2,116,1,106,2,155, + 0,100,3,157,5,83,0,41,4,250,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,8, + 60,109,111,100,117,108,101,32,122,2,32,40,122,2,41,62, + 41,3,114,1,0,0,0,114,159,0,0,0,114,137,0,0, + 0,41,1,114,95,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,98,0,0,0,206,2,0,0, + 115,2,0,0,0,0,7,122,27,66,117,105,108,116,105,110, + 73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95, + 114,101,112,114,78,99,4,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,46, + 0,0,0,124,2,100,0,107,9,114,12,100,0,83,0,116, + 0,160,1,124,1,161,1,114,38,116,2,124,1,124,0,124, + 0,106,3,100,1,141,3,83,0,100,0,83,0,100,0,83, + 0,169,2,78,114,136,0,0,0,41,4,114,56,0,0,0, + 90,10,105,115,95,98,117,105,108,116,105,110,114,90,0,0, + 0,114,137,0,0,0,169,4,218,3,99,108,115,114,80,0, + 0,0,218,4,112,97,116,104,218,6,116,97,114,103,101,116, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 9,102,105,110,100,95,115,112,101,99,215,2,0,0,115,10, + 0,0,0,0,2,8,1,4,1,10,1,16,2,122,25,66, 117,105,108,116,105,110,73,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,2,0,0,0,4,0,0,0,67, - 0,0,0,115,46,0,0,0,124,1,106,0,116,1,106,2, - 107,7,114,34,116,3,100,1,160,4,124,1,106,0,161,1, - 124,1,106,0,100,2,141,2,130,1,116,5,116,6,106,7, - 124,1,131,2,83,0,41,3,122,24,67,114,101,97,116,101, - 32,97,32,98,117,105,108,116,45,105,110,32,109,111,100,117, - 108,101,114,76,0,0,0,114,16,0,0,0,41,8,114,17, - 0,0,0,114,15,0,0,0,114,77,0,0,0,114,78,0, - 0,0,114,44,0,0,0,114,66,0,0,0,114,56,0,0, - 0,90,14,99,114,101,97,116,101,95,98,117,105,108,116,105, - 110,41,2,114,30,0,0,0,114,94,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,148,0,0, - 0,236,2,0,0,115,10,0,0,0,0,3,12,1,12,1, - 4,255,6,2,122,29,66,117,105,108,116,105,110,73,109,112, - 111,114,116,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,3,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,116,1,106,2,124,1,131,2,1,0,100,1,83, - 0,41,2,122,22,69,120,101,99,32,97,32,98,117,105,108, - 116,45,105,110,32,109,111,100,117,108,101,78,41,3,114,66, - 0,0,0,114,56,0,0,0,90,12,101,120,101,99,95,98, - 117,105,108,116,105,110,41,2,114,30,0,0,0,114,95,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,149,0,0,0,244,2,0,0,115,2,0,0,0,0, - 3,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2, + 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,107,9,114,26,124,3,106,1,83,0, + 100,1,83,0,41,2,122,175,70,105,110,100,32,116,104,101, + 32,98,117,105,108,116,45,105,110,32,109,111,100,117,108,101, + 46,10,10,32,32,32,32,32,32,32,32,73,102,32,39,112, + 97,116,104,39,32,105,115,32,101,118,101,114,32,115,112,101, + 99,105,102,105,101,100,32,116,104,101,110,32,116,104,101,32, + 115,101,97,114,99,104,32,105,115,32,99,111,110,115,105,100, + 101,114,101,100,32,97,32,102,97,105,108,117,114,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,41,2,114,166,0,0,0,114, + 108,0,0,0,41,4,114,163,0,0,0,114,80,0,0,0, + 114,164,0,0,0,114,94,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,11,102,105,110,100,95, + 109,111,100,117,108,101,224,2,0,0,115,4,0,0,0,0, + 9,12,1,122,27,66,117,105,108,116,105,110,73,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,2,0,0, + 0,4,0,0,0,67,0,0,0,115,46,0,0,0,124,1, + 106,0,116,1,106,2,107,7,114,34,116,3,100,1,160,4, + 124,1,106,0,161,1,124,1,106,0,100,2,141,2,130,1, + 116,5,116,6,106,7,124,1,131,2,83,0,41,3,122,24, + 67,114,101,97,116,101,32,97,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,114,76,0,0,0,114,16,0, + 0,0,41,8,114,17,0,0,0,114,15,0,0,0,114,77, + 0,0,0,114,78,0,0,0,114,44,0,0,0,114,66,0, + 0,0,114,56,0,0,0,90,14,99,114,101,97,116,101,95, + 98,117,105,108,116,105,110,41,2,114,30,0,0,0,114,94, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,148,0,0,0,236,2,0,0,115,10,0,0,0, + 0,3,12,1,12,1,4,255,6,2,122,29,66,117,105,108, + 116,105,110,73,109,112,111,114,116,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,3,0,0,0,67,0, + 0,0,115,16,0,0,0,116,0,116,1,106,2,124,1,131, + 2,1,0,100,1,83,0,41,2,122,22,69,120,101,99,32, + 97,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,78,41,3,114,66,0,0,0,114,56,0,0,0,90,12, + 101,120,101,99,95,98,117,105,108,116,105,110,41,2,114,30, + 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,149,0,0,0,244,2,0,0, + 115,2,0,0,0,0,3,122,27,66,117,105,108,116,105,110, + 73,109,112,111,114,116,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,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,41,2,122,57,82,101,116,117,114,110, + 32,78,111,110,101,32,97,115,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,115,32,100,111,32,110,111,116, + 32,104,97,118,101,32,99,111,100,101,32,111,98,106,101,99, + 116,115,46,78,114,10,0,0,0,169,2,114,163,0,0,0, + 114,80,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,8,103,101,116,95,99,111,100,101,249,2, + 0,0,115,2,0,0,0,0,4,122,24,66,117,105,108,116, + 105,110,73,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, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,83,0,41,2,122,56,82,101,116,117,114,110,32, + 78,111,110,101,32,97,115,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,115,32,100,111,32,110,111,116,32, + 104,97,118,101,32,115,111,117,114,99,101,32,99,111,100,101, + 46,78,114,10,0,0,0,114,168,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,10,103,101,116, + 95,115,111,117,114,99,101,255,2,0,0,115,2,0,0,0, + 0,4,122,26,66,117,105,108,116,105,110,73,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,2,0,0,0,1, 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, - 41,2,122,57,82,101,116,117,114,110,32,78,111,110,101,32, - 97,115,32,98,117,105,108,116,45,105,110,32,109,111,100,117, - 108,101,115,32,100,111,32,110,111,116,32,104,97,118,101,32, - 99,111,100,101,32,111,98,106,101,99,116,115,46,78,114,10, - 0,0,0,169,2,114,163,0,0,0,114,80,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 103,101,116,95,99,111,100,101,249,2,0,0,115,2,0,0, - 0,0,4,122,24,66,117,105,108,116,105,110,73,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,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,122,56,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,115,32,100,111,32,110,111,116,32,104,97,118,101,32,115, - 111,117,114,99,101,32,99,111,100,101,46,78,114,10,0,0, - 0,114,168,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,10,103,101,116,95,115,111,117,114,99, - 101,255,2,0,0,115,2,0,0,0,0,4,122,26,66,117, - 105,108,116,105,110,73,109,112,111,114,116,101,114,46,103,101, + 41,2,122,52,82,101,116,117,114,110,32,70,97,108,115,101, + 32,97,115,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,115,32,97,114,101,32,110,101,118,101,114,32,112, + 97,99,107,97,103,101,115,46,70,114,10,0,0,0,114,168, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,114,0,0,0,5,3,0,0,115,2,0,0,0, + 0,4,122,26,66,117,105,108,116,105,110,73,109,112,111,114, + 116,101,114,46,105,115,95,112,97,99,107,97,103,101,41,2, + 78,78,41,1,78,41,18,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,3,0,0,0,114,137,0,0,0, + 218,12,115,116,97,116,105,99,109,101,116,104,111,100,114,98, + 0,0,0,218,11,99,108,97,115,115,109,101,116,104,111,100, + 114,166,0,0,0,114,167,0,0,0,114,148,0,0,0,114, + 149,0,0,0,114,85,0,0,0,114,169,0,0,0,114,170, + 0,0,0,114,114,0,0,0,114,96,0,0,0,114,154,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,159,0,0,0,195,2,0,0,115, + 44,0,0,0,8,2,4,7,4,2,2,1,10,8,2,1, + 12,8,2,1,12,11,2,1,10,7,2,1,10,4,2,1, + 2,1,12,4,2,1,2,1,12,4,2,1,2,1,12,4, + 114,159,0,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,144, + 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, + 2,90,4,101,5,100,3,100,4,132,0,131,1,90,6,101, + 7,100,22,100,6,100,7,132,1,131,1,90,8,101,7,100, + 23,100,8,100,9,132,1,131,1,90,9,101,7,100,10,100, + 11,132,0,131,1,90,10,101,5,100,12,100,13,132,0,131, + 1,90,11,101,7,100,14,100,15,132,0,131,1,90,12,101, + 7,101,13,100,16,100,17,132,0,131,1,131,1,90,14,101, + 7,101,13,100,18,100,19,132,0,131,1,131,1,90,15,101, + 7,101,13,100,20,100,21,132,0,131,1,131,1,90,16,100, + 5,83,0,41,24,218,14,70,114,111,122,101,110,73,109,112, + 111,114,116,101,114,122,142,77,101,116,97,32,112,97,116,104, + 32,105,109,112,111,114,116,32,102,111,114,32,102,114,111,122, + 101,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, + 32,65,108,108,32,109,101,116,104,111,100,115,32,97,114,101, + 32,101,105,116,104,101,114,32,99,108,97,115,115,32,111,114, + 32,115,116,97,116,105,99,32,109,101,116,104,111,100,115,32, + 116,111,32,97,118,111,105,100,32,116,104,101,32,110,101,101, + 100,32,116,111,10,32,32,32,32,105,110,115,116,97,110,116, + 105,97,116,101,32,116,104,101,32,99,108,97,115,115,46,10, + 10,32,32,32,32,90,6,102,114,111,122,101,110,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,16,0,0,0,100,1,160,0,124, + 0,106,1,116,2,106,3,161,2,83,0,41,2,114,160,0, + 0,0,114,152,0,0,0,41,4,114,44,0,0,0,114,1, + 0,0,0,114,173,0,0,0,114,137,0,0,0,41,1,218, + 1,109,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,98,0,0,0,25,3,0,0,115,2,0,0,0,0, + 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, + 114,46,109,111,100,117,108,101,95,114,101,112,114,78,99,4, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5, + 0,0,0,67,0,0,0,115,34,0,0,0,116,0,160,1, + 124,1,161,1,114,26,116,2,124,1,124,0,124,0,106,3, + 100,1,141,3,83,0,100,0,83,0,100,0,83,0,114,161, + 0,0,0,41,4,114,56,0,0,0,114,87,0,0,0,114, + 90,0,0,0,114,137,0,0,0,114,162,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,166,0, + 0,0,34,3,0,0,115,6,0,0,0,0,2,10,1,16, + 2,122,24,70,114,111,122,101,110,73,109,112,111,114,116,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,3,0,0,0,3,0,0,0, + 67,0,0,0,115,18,0,0,0,116,0,160,1,124,1,161, + 1,114,14,124,0,83,0,100,1,83,0,41,2,122,93,70, + 105,110,100,32,97,32,102,114,111,122,101,110,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,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,2,114, + 56,0,0,0,114,87,0,0,0,41,3,114,163,0,0,0, + 114,80,0,0,0,114,164,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,167,0,0,0,41,3, + 0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,101, + 110,73,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,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,122,42,85,115,101,32,100, + 101,102,97,117,108,116,32,115,101,109,97,110,116,105,99,115, + 32,102,111,114,32,109,111,100,117,108,101,32,99,114,101,97, + 116,105,111,110,46,78,114,10,0,0,0,41,2,114,163,0, + 0,0,114,94,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,148,0,0,0,50,3,0,0,115, + 2,0,0,0,0,2,122,28,70,114,111,122,101,110,73,109, + 112,111,114,116,101,114,46,99,114,101,97,116,101,95,109,111, + 100,117,108,101,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,124,0,106,0,106,1,125,1,116,2,160,3,124,1, + 161,1,115,36,116,4,100,1,160,5,124,1,161,1,124,1, + 100,2,141,2,130,1,116,6,116,2,106,7,124,1,131,2, + 125,2,116,8,124,2,124,0,106,9,131,2,1,0,100,0, + 83,0,114,86,0,0,0,41,10,114,104,0,0,0,114,17, + 0,0,0,114,56,0,0,0,114,87,0,0,0,114,78,0, + 0,0,114,44,0,0,0,114,66,0,0,0,218,17,103,101, + 116,95,102,114,111,122,101,110,95,111,98,106,101,99,116,218, + 4,101,120,101,99,114,7,0,0,0,41,3,114,95,0,0, + 0,114,17,0,0,0,218,4,99,111,100,101,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,149,0,0,0, + 54,3,0,0,115,14,0,0,0,0,2,8,1,10,1,10, + 1,2,255,6,2,12,1,122,26,70,114,111,122,101,110,73, + 109,112,111,114,116,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,3,0,0,0,67,0,0,0,115,10,0,0, + 0,116,0,124,0,124,1,131,2,83,0,41,1,122,95,76, + 111,97,100,32,97,32,102,114,111,122,101,110,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,41,1, + 114,96,0,0,0,114,168,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,154,0,0,0,63,3, + 0,0,115,2,0,0,0,0,7,122,26,70,114,111,122,101, + 110,73,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,2,0,0,0,3,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,160,1,124,1,161,1,83,0,41,1,122, + 45,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, + 102,114,111,122,101,110,32,109,111,100,117,108,101,46,41,2, + 114,56,0,0,0,114,175,0,0,0,114,168,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,169, + 0,0,0,72,3,0,0,115,2,0,0,0,0,4,122,23, + 70,114,111,122,101,110,73,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,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,83,0,41,2,122,54,82,101,116, + 117,114,110,32,78,111,110,101,32,97,115,32,102,114,111,122, + 101,110,32,109,111,100,117,108,101,115,32,100,111,32,110,111, + 116,32,104,97,118,101,32,115,111,117,114,99,101,32,99,111, + 100,101,46,78,114,10,0,0,0,114,168,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,170,0, + 0,0,78,3,0,0,115,2,0,0,0,0,4,122,25,70, + 114,111,122,101,110,73,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,2,0,0,0,1,0,0,0,67,0,0, - 0,115,4,0,0,0,100,1,83,0,41,2,122,52,82,101, - 116,117,114,110,32,70,97,108,115,101,32,97,115,32,98,117, - 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97, - 114,101,32,110,101,118,101,114,32,112,97,99,107,97,103,101, - 115,46,70,114,10,0,0,0,114,168,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,114,0,0, - 0,5,3,0,0,115,2,0,0,0,0,4,122,26,66,117, - 105,108,116,105,110,73,109,112,111,114,116,101,114,46,105,115, - 95,112,97,99,107,97,103,101,41,2,78,78,41,1,78,41, - 18,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0, - 114,3,0,0,0,114,137,0,0,0,218,12,115,116,97,116, - 105,99,109,101,116,104,111,100,114,98,0,0,0,218,11,99, - 108,97,115,115,109,101,116,104,111,100,114,166,0,0,0,114, - 167,0,0,0,114,148,0,0,0,114,149,0,0,0,114,85, - 0,0,0,114,169,0,0,0,114,170,0,0,0,114,114,0, - 0,0,114,96,0,0,0,114,155,0,0,0,114,10,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,10,0,0,0,116,0,160,1,124,1,161,1,83,0, + 41,1,122,46,82,101,116,117,114,110,32,84,114,117,101,32, + 105,102,32,116,104,101,32,102,114,111,122,101,110,32,109,111, + 100,117,108,101,32,105,115,32,97,32,112,97,99,107,97,103, + 101,46,41,2,114,56,0,0,0,90,17,105,115,95,102,114, + 111,122,101,110,95,112,97,99,107,97,103,101,114,168,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,159,0,0,0,195,2,0,0,115,44,0,0,0,8,2, - 4,7,4,2,2,1,10,8,2,1,12,8,2,1,12,11, - 2,1,10,7,2,1,10,4,2,1,2,1,12,4,2,1, - 2,1,12,4,2,1,2,1,12,4,114,159,0,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,144,0,0,0,101,0,90, - 1,100,0,90,2,100,1,90,3,100,2,90,4,101,5,100, - 3,100,4,132,0,131,1,90,6,101,7,100,22,100,6,100, - 7,132,1,131,1,90,8,101,7,100,23,100,8,100,9,132, - 1,131,1,90,9,101,7,100,10,100,11,132,0,131,1,90, - 10,101,5,100,12,100,13,132,0,131,1,90,11,101,7,100, - 14,100,15,132,0,131,1,90,12,101,7,101,13,100,16,100, - 17,132,0,131,1,131,1,90,14,101,7,101,13,100,18,100, - 19,132,0,131,1,131,1,90,15,101,7,101,13,100,20,100, - 21,132,0,131,1,131,1,90,16,100,5,83,0,41,24,218, - 14,70,114,111,122,101,110,73,109,112,111,114,116,101,114,122, - 142,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114, - 116,32,102,111,114,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,115,46,10,10,32,32,32,32,65,108,108,32,109, - 101,116,104,111,100,115,32,97,114,101,32,101,105,116,104,101, - 114,32,99,108,97,115,115,32,111,114,32,115,116,97,116,105, - 99,32,109,101,116,104,111,100,115,32,116,111,32,97,118,111, - 105,100,32,116,104,101,32,110,101,101,100,32,116,111,10,32, - 32,32,32,105,110,115,116,97,110,116,105,97,116,101,32,116, - 104,101,32,99,108,97,115,115,46,10,10,32,32,32,32,90, - 6,102,114,111,122,101,110,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,16,0,0,0,100,1,160,0,124,0,106,1,116,2,106, - 3,161,2,83,0,41,2,114,160,0,0,0,114,152,0,0, - 0,41,4,114,44,0,0,0,114,1,0,0,0,114,173,0, - 0,0,114,137,0,0,0,41,1,218,1,109,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,98,0,0,0, - 25,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,46,109,111,100,117, - 108,101,95,114,101,112,114,78,99,4,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, - 0,115,34,0,0,0,116,0,160,1,124,1,161,1,114,26, - 116,2,124,1,124,0,124,0,106,3,100,1,141,3,83,0, - 100,0,83,0,100,0,83,0,114,161,0,0,0,41,4,114, - 56,0,0,0,114,87,0,0,0,114,90,0,0,0,114,137, - 0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,166,0,0,0,34,3,0,0, - 115,6,0,0,0,0,2,10,1,16,2,122,24,70,114,111, - 122,101,110,73,109,112,111,114,116,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,3,0,0,0,3,0,0,0,67,0,0,0,115,18, - 0,0,0,116,0,160,1,124,1,161,1,114,14,124,0,83, - 0,100,1,83,0,41,2,122,93,70,105,110,100,32,97,32, - 102,114,111,122,101,110,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,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,2,114,56,0,0,0,114,87, - 0,0,0,41,3,114,163,0,0,0,114,80,0,0,0,114, - 164,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,167,0,0,0,41,3,0,0,115,2,0,0, - 0,0,7,122,26,70,114,111,122,101,110,73,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,2,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,122,42,85,115,101,32,100,101,102,97,117,108,116, - 32,115,101,109,97,110,116,105,99,115,32,102,111,114,32,109, - 111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,78, - 114,10,0,0,0,41,2,114,163,0,0,0,114,94,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,148,0,0,0,50,3,0,0,115,2,0,0,0,0,2, - 122,28,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,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,124,0,106,0, - 106,1,125,1,116,2,160,3,124,1,161,1,115,36,116,4, - 100,1,160,5,124,1,161,1,124,1,100,2,141,2,130,1, - 116,6,116,2,106,7,124,1,131,2,125,2,116,8,124,2, - 124,0,106,9,131,2,1,0,100,0,83,0,114,86,0,0, - 0,41,10,114,104,0,0,0,114,17,0,0,0,114,56,0, - 0,0,114,87,0,0,0,114,78,0,0,0,114,44,0,0, - 0,114,66,0,0,0,218,17,103,101,116,95,102,114,111,122, - 101,110,95,111,98,106,101,99,116,218,4,101,120,101,99,114, - 7,0,0,0,41,3,114,95,0,0,0,114,17,0,0,0, - 218,4,99,111,100,101,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,149,0,0,0,54,3,0,0,115,14, - 0,0,0,0,2,8,1,10,1,10,1,2,255,6,2,12, - 1,122,26,70,114,111,122,101,110,73,109,112,111,114,116,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,3,0, - 0,0,67,0,0,0,115,10,0,0,0,116,0,124,0,124, - 1,131,2,83,0,41,1,122,95,76,111,97,100,32,97,32, - 102,114,111,122,101,110,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,41,1,114,96,0,0,0,114, - 168,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,155,0,0,0,63,3,0,0,115,2,0,0, - 0,0,7,122,26,70,114,111,122,101,110,73,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,2,0,0,0, - 3,0,0,0,67,0,0,0,115,10,0,0,0,116,0,160, - 1,124,1,161,1,83,0,41,1,122,45,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,102,114,111,122,101,110, - 32,109,111,100,117,108,101,46,41,2,114,56,0,0,0,114, - 175,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,169,0,0,0,72,3,0, - 0,115,2,0,0,0,0,4,122,23,70,114,111,122,101,110, - 73,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,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,83,0,41,2,122,54,82,101,116,117,114,110,32,78,111, - 110,101,32,97,115,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, - 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,10, - 0,0,0,114,168,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,170,0,0,0,78,3,0,0, - 115,2,0,0,0,0,4,122,25,70,114,111,122,101,110,73, - 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,2, - 0,0,0,3,0,0,0,67,0,0,0,115,10,0,0,0, - 116,0,160,1,124,1,161,1,83,0,41,1,122,46,82,101, - 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,32,105, - 115,32,97,32,112,97,99,107,97,103,101,46,41,2,114,56, - 0,0,0,90,17,105,115,95,102,114,111,122,101,110,95,112, - 97,99,107,97,103,101,114,168,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,114,0,0,0,84, - 3,0,0,115,2,0,0,0,0,4,122,25,70,114,111,122, - 101,110,73,109,112,111,114,116,101,114,46,105,115,95,112,97, - 99,107,97,103,101,41,2,78,78,41,1,78,41,17,114,1, + 114,114,0,0,0,84,3,0,0,115,2,0,0,0,0,4, + 122,25,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,105,115,95,112,97,99,107,97,103,101,41,2,78,78,41, + 1,78,41,17,114,1,0,0,0,114,0,0,0,0,114,2, + 0,0,0,114,3,0,0,0,114,137,0,0,0,114,171,0, + 0,0,114,98,0,0,0,114,172,0,0,0,114,166,0,0, + 0,114,167,0,0,0,114,148,0,0,0,114,149,0,0,0, + 114,154,0,0,0,114,89,0,0,0,114,169,0,0,0,114, + 170,0,0,0,114,114,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,173,0, + 0,0,14,3,0,0,115,46,0,0,0,8,2,4,7,4, + 2,2,1,10,8,2,1,12,6,2,1,12,8,2,1,10, + 3,2,1,10,8,2,1,10,8,2,1,2,1,12,4,2, + 1,2,1,12,4,2,1,2,1,114,173,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,132,0,90,5,100,6,83,0,41,7,218,18, + 95,73,109,112,111,114,116,76,111,99,107,67,111,110,116,101, + 120,116,122,36,67,111,110,116,101,120,116,32,109,97,110,97, + 103,101,114,32,102,111,114,32,116,104,101,32,105,109,112,111, + 114,116,32,108,111,99,107,46,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,12,0,0,0,116,0,160,1,161,0,1,0,100,1, + 83,0,41,2,122,24,65,99,113,117,105,114,101,32,116,104, + 101,32,105,109,112,111,114,116,32,108,111,99,107,46,78,41, + 2,114,56,0,0,0,114,57,0,0,0,114,46,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 53,0,0,0,97,3,0,0,115,2,0,0,0,0,2,122, + 28,95,73,109,112,111,114,116,76,111,99,107,67,111,110,116, + 101,120,116,46,95,95,101,110,116,101,114,95,95,99,4,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,2,0, + 0,0,67,0,0,0,115,12,0,0,0,116,0,160,1,161, + 0,1,0,100,1,83,0,41,2,122,60,82,101,108,101,97, + 115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,111, + 99,107,32,114,101,103,97,114,100,108,101,115,115,32,111,102, + 32,97,110,121,32,114,97,105,115,101,100,32,101,120,99,101, + 112,116,105,111,110,115,46,78,41,2,114,56,0,0,0,114, + 59,0,0,0,41,4,114,30,0,0,0,218,8,101,120,99, + 95,116,121,112,101,218,9,101,120,99,95,118,97,108,117,101, + 218,13,101,120,99,95,116,114,97,99,101,98,97,99,107,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,55, + 0,0,0,101,3,0,0,115,2,0,0,0,0,2,122,27, + 95,73,109,112,111,114,116,76,111,99,107,67,111,110,116,101, + 120,116,46,95,95,101,120,105,116,95,95,78,41,6,114,1, 0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,0, - 0,0,114,137,0,0,0,114,171,0,0,0,114,98,0,0, - 0,114,172,0,0,0,114,166,0,0,0,114,167,0,0,0, - 114,148,0,0,0,114,149,0,0,0,114,155,0,0,0,114, - 89,0,0,0,114,169,0,0,0,114,170,0,0,0,114,114, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,173,0,0,0,14,3,0,0, - 115,46,0,0,0,8,2,4,7,4,2,2,1,10,8,2, - 1,12,6,2,1,12,8,2,1,10,3,2,1,10,8,2, - 1,10,8,2,1,2,1,12,4,2,1,2,1,12,4,2, - 1,2,1,114,173,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,132,0, - 90,5,100,6,83,0,41,7,218,18,95,73,109,112,111,114, - 116,76,111,99,107,67,111,110,116,101,120,116,122,36,67,111, - 110,116,101,120,116,32,109,97,110,97,103,101,114,32,102,111, - 114,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,46,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,12,0,0,0, - 116,0,160,1,161,0,1,0,100,1,83,0,41,2,122,24, - 65,99,113,117,105,114,101,32,116,104,101,32,105,109,112,111, - 114,116,32,108,111,99,107,46,78,41,2,114,56,0,0,0, - 114,57,0,0,0,114,46,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,53,0,0,0,97,3, - 0,0,115,2,0,0,0,0,2,122,28,95,73,109,112,111, - 114,116,76,111,99,107,67,111,110,116,101,120,116,46,95,95, - 101,110,116,101,114,95,95,99,4,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,2,0,0,0,67,0,0,0, - 115,12,0,0,0,116,0,160,1,161,0,1,0,100,1,83, - 0,41,2,122,60,82,101,108,101,97,115,101,32,116,104,101, - 32,105,109,112,111,114,116,32,108,111,99,107,32,114,101,103, - 97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,114, - 97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,115, - 46,78,41,2,114,56,0,0,0,114,58,0,0,0,41,4, - 114,30,0,0,0,218,8,101,120,99,95,116,121,112,101,218, - 9,101,120,99,95,118,97,108,117,101,218,13,101,120,99,95, - 116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,55,0,0,0,101,3,0, - 0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,114, - 116,76,111,99,107,67,111,110,116,101,120,116,46,95,95,101, - 120,105,116,95,95,78,41,6,114,1,0,0,0,114,0,0, - 0,0,114,2,0,0,0,114,3,0,0,0,114,53,0,0, - 0,114,55,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,178,0,0,0,93, - 3,0,0,115,6,0,0,0,8,2,4,2,8,4,114,178, - 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 5,0,0,0,5,0,0,0,67,0,0,0,115,64,0,0, - 0,124,1,160,0,100,1,124,2,100,2,24,0,161,2,125, - 3,116,1,124,3,131,1,124,2,107,0,114,36,116,2,100, - 3,131,1,130,1,124,3,100,4,25,0,125,4,124,0,114, - 60,100,5,160,3,124,4,124,0,161,2,83,0,124,4,83, - 0,41,6,122,50,82,101,115,111,108,118,101,32,97,32,114, - 101,108,97,116,105,118,101,32,109,111,100,117,108,101,32,110, - 97,109,101,32,116,111,32,97,110,32,97,98,115,111,108,117, - 116,101,32,111,110,101,46,114,127,0,0,0,114,37,0,0, - 0,122,50,97,116,116,101,109,112,116,101,100,32,114,101,108, - 97,116,105,118,101,32,105,109,112,111,114,116,32,98,101,121, - 111,110,100,32,116,111,112,45,108,101,118,101,108,32,112,97, - 99,107,97,103,101,114,22,0,0,0,250,5,123,125,46,123, - 125,41,4,218,6,114,115,112,108,105,116,218,3,108,101,110, - 114,78,0,0,0,114,44,0,0,0,41,5,114,17,0,0, - 0,218,7,112,97,99,107,97,103,101,218,5,108,101,118,101, - 108,90,4,98,105,116,115,90,4,98,97,115,101,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,13,95,114, - 101,115,111,108,118,101,95,110,97,109,101,106,3,0,0,115, - 10,0,0,0,0,2,16,1,12,1,8,1,8,1,114,187, - 0,0,0,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,34,0,0, - 0,124,0,160,0,124,1,124,2,161,2,125,3,124,3,100, - 0,107,8,114,24,100,0,83,0,116,1,124,1,124,3,131, - 2,83,0,114,13,0,0,0,41,2,114,167,0,0,0,114, - 90,0,0,0,41,4,218,6,102,105,110,100,101,114,114,17, - 0,0,0,114,164,0,0,0,114,108,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,218,17,95,102, - 105,110,100,95,115,112,101,99,95,108,101,103,97,99,121,115, - 3,0,0,115,8,0,0,0,0,3,12,1,8,1,4,1, - 114,189,0,0,0,99,3,0,0,0,0,0,0,0,0,0, - 0,0,10,0,0,0,10,0,0,0,67,0,0,0,115,12, - 1,0,0,116,0,106,1,125,3,124,3,100,1,107,8,114, - 22,116,2,100,2,131,1,130,1,124,3,115,38,116,3,160, - 4,100,3,116,5,161,2,1,0,124,0,116,0,106,6,107, - 6,125,4,124,3,68,0,93,210,125,5,116,7,131,0,143, - 84,1,0,122,10,124,5,106,8,125,6,87,0,110,54,4, - 0,116,9,107,10,114,128,1,0,1,0,1,0,116,10,124, - 5,124,0,124,1,131,3,125,7,124,7,100,1,107,8,114, - 124,89,0,87,0,53,0,81,0,82,0,163,0,113,52,89, - 0,110,14,88,0,124,6,124,0,124,1,124,2,131,3,125, - 7,87,0,53,0,81,0,82,0,88,0,124,7,100,1,107, - 9,114,52,124,4,144,0,115,254,124,0,116,0,106,6,107, - 6,144,0,114,254,116,0,106,6,124,0,25,0,125,8,122, - 10,124,8,106,11,125,9,87,0,110,28,4,0,116,9,107, - 10,114,226,1,0,1,0,1,0,124,7,6,0,89,0,2, - 0,1,0,83,0,88,0,124,9,100,1,107,8,114,244,124, - 7,2,0,1,0,83,0,124,9,2,0,1,0,83,0,113, - 52,124,7,2,0,1,0,83,0,113,52,100,1,83,0,41, - 4,122,21,70,105,110,100,32,97,32,109,111,100,117,108,101, - 39,115,32,115,112,101,99,46,78,122,53,115,121,115,46,109, - 101,116,97,95,112,97,116,104,32,105,115,32,78,111,110,101, - 44,32,80,121,116,104,111,110,32,105,115,32,108,105,107,101, - 108,121,32,115,104,117,116,116,105,110,103,32,100,111,119,110, - 122,22,115,121,115,46,109,101,116,97,95,112,97,116,104,32, - 105,115,32,101,109,112,116,121,41,12,114,15,0,0,0,218, - 9,109,101,116,97,95,112,97,116,104,114,78,0,0,0,218, - 9,95,119,97,114,110,105,110,103,115,218,4,119,97,114,110, - 218,13,73,109,112,111,114,116,87,97,114,110,105,110,103,114, - 91,0,0,0,114,178,0,0,0,114,166,0,0,0,114,105, - 0,0,0,114,189,0,0,0,114,104,0,0,0,41,10,114, - 17,0,0,0,114,164,0,0,0,114,165,0,0,0,114,190, - 0,0,0,90,9,105,115,95,114,101,108,111,97,100,114,188, - 0,0,0,114,166,0,0,0,114,94,0,0,0,114,95,0, - 0,0,114,104,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,10,95,102,105,110,100,95,115,112, - 101,99,124,3,0,0,115,54,0,0,0,0,2,6,1,8, - 2,8,3,4,1,12,5,10,1,8,1,8,1,2,1,10, - 1,14,1,12,1,8,1,20,2,22,1,8,2,18,1,10, - 1,2,1,10,1,14,4,14,2,8,1,8,2,10,2,10, - 2,114,194,0,0,0,99,3,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,115, - 108,0,0,0,116,0,124,0,116,1,131,2,115,28,116,2, - 100,1,160,3,116,4,124,0,131,1,161,1,131,1,130,1, - 124,2,100,2,107,0,114,44,116,5,100,3,131,1,130,1, - 124,2,100,2,107,4,114,84,116,0,124,1,116,1,131,2, - 115,72,116,2,100,4,131,1,130,1,110,12,124,1,115,84, - 116,6,100,5,131,1,130,1,124,0,115,104,124,2,100,2, - 107,2,114,104,116,5,100,6,131,1,130,1,100,7,83,0, - 41,8,122,28,86,101,114,105,102,121,32,97,114,103,117,109, - 101,110,116,115,32,97,114,101,32,34,115,97,110,101,34,46, - 122,31,109,111,100,117,108,101,32,110,97,109,101,32,109,117, - 115,116,32,98,101,32,115,116,114,44,32,110,111,116,32,123, - 125,114,22,0,0,0,122,18,108,101,118,101,108,32,109,117, - 115,116,32,98,101,32,62,61,32,48,122,31,95,95,112,97, - 99,107,97,103,101,95,95,32,110,111,116,32,115,101,116,32, - 116,111,32,97,32,115,116,114,105,110,103,122,54,97,116,116, - 101,109,112,116,101,100,32,114,101,108,97,116,105,118,101,32, - 105,109,112,111,114,116,32,119,105,116,104,32,110,111,32,107, - 110,111,119,110,32,112,97,114,101,110,116,32,112,97,99,107, - 97,103,101,122,17,69,109,112,116,121,32,109,111,100,117,108, - 101,32,110,97,109,101,78,41,7,218,10,105,115,105,110,115, - 116,97,110,99,101,218,3,115,116,114,218,9,84,121,112,101, - 69,114,114,111,114,114,44,0,0,0,114,14,0,0,0,218, - 10,86,97,108,117,101,69,114,114,111,114,114,78,0,0,0, - 169,3,114,17,0,0,0,114,185,0,0,0,114,186,0,0, + 0,0,114,53,0,0,0,114,55,0,0,0,114,10,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,171, - 3,0,0,115,22,0,0,0,0,2,10,1,18,1,8,1, - 8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,200, - 0,0,0,122,16,78,111,32,109,111,100,117,108,101,32,110, - 97,109,101,100,32,122,4,123,33,114,125,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,220,0,0,0,100,0,125,2,124,0,160, - 0,100,1,161,1,100,2,25,0,125,3,124,3,114,134,124, - 3,116,1,106,2,107,7,114,42,116,3,124,1,124,3,131, - 2,1,0,124,0,116,1,106,2,107,6,114,62,116,1,106, - 2,124,0,25,0,83,0,116,1,106,2,124,3,25,0,125, - 4,122,10,124,4,106,4,125,2,87,0,110,50,4,0,116, - 5,107,10,114,132,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,88,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,107,8,114, - 172,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,114, - 216,116,1,106,2,124,3,25,0,125,4,116,11,124,4,124, - 0,160,0,100,1,161,1,100,5,25,0,124,7,131,3,1, - 0,124,7,83,0,41,6,78,114,127,0,0,0,114,22,0, - 0,0,122,23,59,32,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,112,97,99,107,97,103,101,114,16,0,0,0, - 233,2,0,0,0,41,12,114,128,0,0,0,114,15,0,0, - 0,114,91,0,0,0,114,66,0,0,0,114,140,0,0,0, - 114,105,0,0,0,218,8,95,69,82,82,95,77,83,71,114, - 44,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,114,194,0,0,0,114,158, - 0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218, - 7,105,109,112,111,114,116,95,114,164,0,0,0,114,129,0, - 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, - 101,114,156,0,0,0,114,94,0,0,0,114,95,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 23,95,102,105,110,100,95,97,110,100,95,108,111,97,100,95, - 117,110,108,111,99,107,101,100,190,3,0,0,115,42,0,0, - 0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10, - 1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8, - 1,20,2,8,1,4,2,10,1,22,1,114,205,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0, - 124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0, - 116,4,161,2,125,2,124,2,116,4,107,8,114,54,116,5, - 124,0,124,1,131,2,87,0,2,0,53,0,81,0,82,0, - 163,0,83,0,87,0,53,0,81,0,82,0,88,0,124,2, - 100,1,107,8,114,94,100,2,160,6,124,0,161,1,125,3, - 116,7,124,3,124,0,100,3,141,2,130,1,116,8,124,0, - 131,1,1,0,124,2,83,0,41,4,122,25,70,105,110,100, - 32,97,110,100,32,108,111,97,100,32,116,104,101,32,109,111, - 100,117,108,101,46,78,122,40,105,109,112,111,114,116,32,111, - 102,32,123,125,32,104,97,108,116,101,100,59,32,78,111,110, - 101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,115, - 114,16,0,0,0,41,9,114,49,0,0,0,114,15,0,0, - 0,114,91,0,0,0,114,34,0,0,0,218,14,95,78,69, - 69,68,83,95,76,79,65,68,73,78,71,114,205,0,0,0, - 114,44,0,0,0,114,203,0,0,0,114,64,0,0,0,41, - 4,114,17,0,0,0,114,204,0,0,0,114,95,0,0,0, - 114,74,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, - 108,111,97,100,220,3,0,0,115,22,0,0,0,0,2,10, - 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, - 2,8,1,114,207,0,0,0,114,22,0,0,0,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,42,0,0,0,116,0,124,0,124, - 1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,116, - 1,124,0,124,1,124,2,131,3,125,0,116,2,124,0,116, - 3,131,2,83,0,41,2,97,50,1,0,0,73,109,112,111, - 114,116,32,97,110,100,32,114,101,116,117,114,110,32,116,104, - 101,32,109,111,100,117,108,101,32,98,97,115,101,100,32,111, - 110,32,105,116,115,32,110,97,109,101,44,32,116,104,101,32, - 112,97,99,107,97,103,101,32,116,104,101,32,99,97,108,108, - 32,105,115,10,32,32,32,32,98,101,105,110,103,32,109,97, - 100,101,32,102,114,111,109,44,32,97,110,100,32,116,104,101, - 32,108,101,118,101,108,32,97,100,106,117,115,116,109,101,110, - 116,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, - 99,116,105,111,110,32,114,101,112,114,101,115,101,110,116,115, - 32,116,104,101,32,103,114,101,97,116,101,115,116,32,99,111, - 109,109,111,110,32,100,101,110,111,109,105,110,97,116,111,114, - 32,111,102,32,102,117,110,99,116,105,111,110,97,108,105,116, - 121,10,32,32,32,32,98,101,116,119,101,101,110,32,105,109, - 112,111,114,116,95,109,111,100,117,108,101,32,97,110,100,32, - 95,95,105,109,112,111,114,116,95,95,46,32,84,104,105,115, - 32,105,110,99,108,117,100,101,115,32,115,101,116,116,105,110, - 103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102, - 10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32, - 100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,22, - 0,0,0,41,4,114,200,0,0,0,114,187,0,0,0,114, - 207,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, - 116,114,199,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,208,0,0,0,236,3,0,0,115,8, - 0,0,0,0,9,12,1,8,1,12,1,114,208,0,0,0, - 169,1,218,9,114,101,99,117,114,115,105,118,101,99,3,0, - 0,0,0,0,0,0,1,0,0,0,8,0,0,0,11,0, - 0,0,67,0,0,0,115,226,0,0,0,124,1,68,0,93, - 216,125,4,116,0,124,4,116,1,131,2,115,66,124,3,114, - 34,124,0,106,2,100,1,23,0,125,5,110,4,100,2,125, - 5,116,3,100,3,124,5,155,0,100,4,116,4,124,4,131, - 1,106,2,155,0,157,4,131,1,130,1,113,4,124,4,100, - 5,107,2,114,108,124,3,115,220,116,5,124,0,100,6,131, - 2,114,220,116,6,124,0,124,0,106,7,124,2,100,7,100, - 8,141,4,1,0,113,4,116,5,124,0,124,4,131,2,115, - 4,100,9,160,8,124,0,106,2,124,4,161,2,125,6,122, - 14,116,9,124,2,124,6,131,2,1,0,87,0,113,4,4, - 0,116,10,107,10,114,218,1,0,125,7,1,0,122,42,124, - 7,106,11,124,6,107,2,114,200,116,12,106,13,160,14,124, - 6,116,15,161,2,100,10,107,9,114,200,87,0,89,0,162, - 8,113,4,130,0,87,0,53,0,100,10,125,7,126,7,88, - 0,89,0,113,4,88,0,113,4,124,0,83,0,41,11,122, - 238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,116, - 32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,117, - 108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,32, - 84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,97, - 109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,97, - 98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,117, - 108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,116, - 46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,100, - 32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,101, - 32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,97, - 115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,105, - 98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,115, - 32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,122, - 8,46,95,95,97,108,108,95,95,122,13,96,96,102,114,111, - 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, - 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, - 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, - 95,95,84,114,209,0,0,0,114,182,0,0,0,78,41,16, - 114,195,0,0,0,114,196,0,0,0,114,1,0,0,0,114, - 197,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16, - 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, - 114,212,0,0,0,114,44,0,0,0,114,66,0,0,0,114, - 203,0,0,0,114,17,0,0,0,114,15,0,0,0,114,91, - 0,0,0,114,34,0,0,0,114,206,0,0,0,41,8,114, - 95,0,0,0,218,8,102,114,111,109,108,105,115,116,114,204, - 0,0,0,114,210,0,0,0,218,1,120,90,5,119,104,101, - 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, - 120,99,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,213,0,0,0,251,3,0,0,115,44,0,0,0,0, - 10,8,1,10,1,4,1,12,2,4,1,28,2,8,1,14, - 1,10,1,2,255,8,2,10,1,14,1,2,1,14,1,16, - 4,10,1,16,255,2,2,8,1,22,1,114,213,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0, - 160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1, - 125,2,124,1,100,3,107,9,114,82,124,2,100,3,107,9, - 114,78,124,1,124,2,106,1,107,3,114,78,116,2,106,3, - 100,4,124,1,155,2,100,5,124,2,106,1,155,2,100,6, - 157,5,116,4,100,7,100,8,141,3,1,0,124,1,83,0, - 124,2,100,3,107,9,114,96,124,2,106,1,83,0,116,2, - 106,3,100,9,116,4,100,7,100,8,141,3,1,0,124,0, - 100,10,25,0,125,1,100,11,124,0,107,7,114,142,124,1, - 160,5,100,12,161,1,100,13,25,0,125,1,124,1,83,0, - 41,14,122,167,67,97,108,99,117,108,97,116,101,32,119,104, - 97,116,32,95,95,112,97,99,107,97,103,101,95,95,32,115, - 104,111,117,108,100,32,98,101,46,10,10,32,32,32,32,95, - 95,112,97,99,107,97,103,101,95,95,32,105,115,32,110,111, - 116,32,103,117,97,114,97,110,116,101,101,100,32,116,111,32, - 98,101,32,100,101,102,105,110,101,100,32,111,114,32,99,111, - 117,108,100,32,98,101,32,115,101,116,32,116,111,32,78,111, - 110,101,10,32,32,32,32,116,111,32,114,101,112,114,101,115, - 101,110,116,32,116,104,97,116,32,105,116,115,32,112,114,111, - 112,101,114,32,118,97,108,117,101,32,105,115,32,117,110,107, - 110,111,119,110,46,10,10,32,32,32,32,114,144,0,0,0, - 114,104,0,0,0,78,122,32,95,95,112,97,99,107,97,103, - 101,95,95,32,33,61,32,95,95,115,112,101,99,95,95,46, - 112,97,114,101,110,116,32,40,122,4,32,33,61,32,250,1, - 41,233,3,0,0,0,41,1,90,10,115,116,97,99,107,108, - 101,118,101,108,122,89,99,97,110,39,116,32,114,101,115,111, - 108,118,101,32,112,97,99,107,97,103,101,32,102,114,111,109, - 32,95,95,115,112,101,99,95,95,32,111,114,32,95,95,112, - 97,99,107,97,103,101,95,95,44,32,102,97,108,108,105,110, - 103,32,98,97,99,107,32,111,110,32,95,95,110,97,109,101, - 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, - 1,0,0,0,114,140,0,0,0,114,127,0,0,0,114,22, - 0,0,0,41,6,114,34,0,0,0,114,129,0,0,0,114, - 191,0,0,0,114,192,0,0,0,114,193,0,0,0,114,128, - 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,185, - 0,0,0,114,94,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, - 95,112,97,99,107,97,103,101,95,95,32,4,0,0,115,38, - 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, - 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, - 254,6,3,8,1,8,1,14,1,114,219,0,0,0,114,10, - 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, - 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, - 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, - 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, - 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, - 7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,107, - 2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,124, - 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, - 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, - 0,25,0,83,0,110,26,116,7,124,5,100,4,131,2,114, - 172,116,8,124,5,124,3,116,0,131,3,83,0,124,5,83, - 0,100,2,83,0,41,5,97,215,1,0,0,73,109,112,111, - 114,116,32,97,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,84,104,101,32,39,103,108,111,98,97,108,115,39,32, - 97,114,103,117,109,101,110,116,32,105,115,32,117,115,101,100, - 32,116,111,32,105,110,102,101,114,32,119,104,101,114,101,32, - 116,104,101,32,105,109,112,111,114,116,32,105,115,32,111,99, - 99,117,114,114,105,110,103,32,102,114,111,109,10,32,32,32, - 32,116,111,32,104,97,110,100,108,101,32,114,101,108,97,116, - 105,118,101,32,105,109,112,111,114,116,115,46,32,84,104,101, - 32,39,108,111,99,97,108,115,39,32,97,114,103,117,109,101, - 110,116,32,105,115,32,105,103,110,111,114,101,100,46,32,84, - 104,101,10,32,32,32,32,39,102,114,111,109,108,105,115,116, - 39,32,97,114,103,117,109,101,110,116,32,115,112,101,99,105, - 102,105,101,115,32,119,104,97,116,32,115,104,111,117,108,100, - 32,101,120,105,115,116,32,97,115,32,97,116,116,114,105,98, - 117,116,101,115,32,111,110,32,116,104,101,32,109,111,100,117, - 108,101,10,32,32,32,32,98,101,105,110,103,32,105,109,112, - 111,114,116,101,100,32,40,101,46,103,46,32,96,96,102,114, - 111,109,32,109,111,100,117,108,101,32,105,109,112,111,114,116, - 32,60,102,114,111,109,108,105,115,116,62,96,96,41,46,32, - 32,84,104,101,32,39,108,101,118,101,108,39,10,32,32,32, - 32,97,114,103,117,109,101,110,116,32,114,101,112,114,101,115, - 101,110,116,115,32,116,104,101,32,112,97,99,107,97,103,101, - 32,108,111,99,97,116,105,111,110,32,116,111,32,105,109,112, - 111,114,116,32,102,114,111,109,32,105,110,32,97,32,114,101, - 108,97,116,105,118,101,10,32,32,32,32,105,109,112,111,114, - 116,32,40,101,46,103,46,32,96,96,102,114,111,109,32,46, - 46,112,107,103,32,105,109,112,111,114,116,32,109,111,100,96, - 96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39, - 108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32, - 32,32,32,114,22,0,0,0,78,114,127,0,0,0,114,140, - 0,0,0,41,9,114,208,0,0,0,114,219,0,0,0,218, - 9,112,97,114,116,105,116,105,111,110,114,184,0,0,0,114, - 15,0,0,0,114,91,0,0,0,114,1,0,0,0,114,4, - 0,0,0,114,213,0,0,0,41,9,114,17,0,0,0,114, - 218,0,0,0,218,6,108,111,99,97,108,115,114,214,0,0, - 0,114,186,0,0,0,114,95,0,0,0,90,8,103,108,111, - 98,97,108,115,95,114,185,0,0,0,90,7,99,117,116,95, - 111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,10,95,95,105,109,112,111,114,116,95,95,59,4, - 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, - 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, - 1,10,1,12,2,114,222,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, - 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, - 23,0,131,1,130,1,116,3,124,1,131,1,83,0,41,2, - 78,122,25,110,111,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,32,110,97,109,101,100,32,41,4,114,159, - 0,0,0,114,166,0,0,0,114,78,0,0,0,114,158,0, - 0,0,41,2,114,17,0,0,0,114,94,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, - 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, - 101,96,4,0,0,115,8,0,0,0,0,1,10,1,8,1, - 12,1,114,223,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0, - 115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116, - 1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93, - 72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,114, - 26,124,3,116,1,106,6,107,6,114,60,116,7,125,5,110, - 18,116,0,160,8,124,3,161,1,114,26,116,9,125,5,110, - 2,113,26,116,10,124,4,124,5,131,2,125,6,116,11,124, - 6,124,4,131,2,1,0,113,26,116,1,106,3,116,12,25, - 0,125,7,100,1,68,0,93,46,125,8,124,8,116,1,106, - 3,107,7,114,138,116,13,124,8,131,1,125,9,110,10,116, - 1,106,3,124,8,25,0,125,9,116,14,124,7,124,8,124, - 9,131,3,1,0,113,114,100,2,83,0,41,3,122,250,83, - 101,116,117,112,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,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,10,32,32,32,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,65,115,32,115,121, - 115,32,105,115,32,110,101,101,100,101,100,32,102,111,114,32, - 115,121,115,46,109,111,100,117,108,101,115,32,97,99,99,101, - 115,115,32,97,110,100,32,95,105,109,112,32,105,115,32,110, - 101,101,100,101,100,32,116,111,32,108,111,97,100,32,98,117, - 105,108,116,45,105,110,10,32,32,32,32,109,111,100,117,108, - 101,115,44,32,116,104,111,115,101,32,116,119,111,32,109,111, - 100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120, - 112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32, - 105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0, - 114,191,0,0,0,114,63,0,0,0,78,41,15,114,56,0, - 0,0,114,15,0,0,0,114,14,0,0,0,114,91,0,0, - 0,218,5,105,116,101,109,115,114,195,0,0,0,114,77,0, - 0,0,114,159,0,0,0,114,87,0,0,0,114,173,0,0, - 0,114,141,0,0,0,114,147,0,0,0,114,1,0,0,0, - 114,223,0,0,0,114,5,0,0,0,41,10,218,10,115,121, - 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, - 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, - 112,101,114,17,0,0,0,114,95,0,0,0,114,108,0,0, - 0,114,94,0,0,0,90,11,115,101,108,102,95,109,111,100, - 117,108,101,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,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,6,95,115,101,116,117,112,103,4,0,0,115,36,0,0, - 0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6, - 1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10, - 1,10,2,10,1,114,227,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,38,0,0,0,116,0,124,0,124,1,131,2, - 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, - 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, - 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, - 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, - 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,78,41,6,114,227,0,0,0,114,15,0,0,0,114, - 190,0,0,0,114,118,0,0,0,114,159,0,0,0,114,173, - 0,0,0,41,2,114,225,0,0,0,114,226,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,105,110,115,116,97,108,108,138,4,0,0,115,6,0,0, - 0,0,2,10,2,12,1,114,228,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, - 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, - 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, - 25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,110, + 114,178,0,0,0,93,3,0,0,115,6,0,0,0,8,2, + 4,2,8,4,114,178,0,0,0,99,3,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, + 0,0,115,64,0,0,0,124,1,160,0,100,1,124,2,100, + 2,24,0,161,2,125,3,116,1,124,3,131,1,124,2,107, + 0,114,36,116,2,100,3,131,1,130,1,124,3,100,4,25, + 0,125,4,124,0,114,60,100,5,160,3,124,4,124,0,161, + 2,83,0,124,4,83,0,41,6,122,50,82,101,115,111,108, + 118,101,32,97,32,114,101,108,97,116,105,118,101,32,109,111, + 100,117,108,101,32,110,97,109,101,32,116,111,32,97,110,32, + 97,98,115,111,108,117,116,101,32,111,110,101,46,114,127,0, + 0,0,114,37,0,0,0,122,50,97,116,116,101,109,112,116, + 101,100,32,114,101,108,97,116,105,118,101,32,105,109,112,111, + 114,116,32,98,101,121,111,110,100,32,116,111,112,45,108,101, + 118,101,108,32,112,97,99,107,97,103,101,114,22,0,0,0, + 250,5,123,125,46,123,125,41,4,218,6,114,115,112,108,105, + 116,218,3,108,101,110,114,78,0,0,0,114,44,0,0,0, + 41,5,114,17,0,0,0,218,7,112,97,99,107,97,103,101, + 218,5,108,101,118,101,108,90,4,98,105,116,115,90,4,98, + 97,115,101,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,13,95,114,101,115,111,108,118,101,95,110,97,109, + 101,106,3,0,0,115,10,0,0,0,0,2,16,1,12,1, + 8,1,8,1,114,187,0,0,0,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,34,0,0,0,124,0,160,0,124,1,124,2,161, + 2,125,3,124,3,100,0,107,8,114,24,100,0,83,0,116, + 1,124,1,124,3,131,2,83,0,114,13,0,0,0,41,2, + 114,167,0,0,0,114,90,0,0,0,41,4,218,6,102,105, + 110,100,101,114,114,17,0,0,0,114,164,0,0,0,114,108, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,17,95,102,105,110,100,95,115,112,101,99,95,108, + 101,103,97,99,121,115,3,0,0,115,8,0,0,0,0,3, + 12,1,8,1,4,1,114,189,0,0,0,99,3,0,0,0, + 0,0,0,0,0,0,0,0,10,0,0,0,10,0,0,0, + 67,0,0,0,115,36,1,0,0,116,0,106,1,125,3,124, + 3,100,1,107,8,114,22,116,2,100,2,131,1,130,1,124, + 3,115,38,116,3,160,4,100,3,116,5,161,2,1,0,124, + 0,116,0,106,6,107,6,125,4,124,3,68,0,93,234,125, + 5,116,7,131,0,143,96,1,0,122,10,124,5,106,8,125, + 6,87,0,110,56,4,0,116,9,107,10,114,130,1,0,1, + 0,1,0,116,10,124,5,124,0,124,1,131,3,125,7,124, + 7,100,1,107,8,114,126,89,0,87,0,100,1,4,0,4, + 0,131,3,1,0,113,52,89,0,110,14,48,0,124,6,124, + 0,124,1,124,2,131,3,125,7,87,0,100,1,4,0,4, + 0,131,3,1,0,110,16,49,0,115,164,48,0,1,0,1, + 0,1,0,89,0,1,0,124,7,100,1,107,9,114,52,124, + 4,144,1,115,22,124,0,116,0,106,6,107,6,144,1,114, + 22,116,0,106,6,124,0,25,0,125,8,122,10,124,8,106, + 11,125,9,87,0,110,28,4,0,116,9,107,10,114,248,1, + 0,1,0,1,0,124,7,6,0,89,0,2,0,1,0,83, + 0,48,0,124,9,100,1,107,8,144,1,114,12,124,7,2, + 0,1,0,83,0,124,9,2,0,1,0,83,0,113,52,124, + 7,2,0,1,0,83,0,113,52,100,1,83,0,41,4,122, + 21,70,105,110,100,32,97,32,109,111,100,117,108,101,39,115, + 32,115,112,101,99,46,78,122,53,115,121,115,46,109,101,116, + 97,95,112,97,116,104,32,105,115,32,78,111,110,101,44,32, + 80,121,116,104,111,110,32,105,115,32,108,105,107,101,108,121, + 32,115,104,117,116,116,105,110,103,32,100,111,119,110,122,22, + 115,121,115,46,109,101,116,97,95,112,97,116,104,32,105,115, + 32,101,109,112,116,121,41,12,114,15,0,0,0,218,9,109, + 101,116,97,95,112,97,116,104,114,78,0,0,0,218,9,95, + 119,97,114,110,105,110,103,115,218,4,119,97,114,110,218,13, + 73,109,112,111,114,116,87,97,114,110,105,110,103,114,91,0, + 0,0,114,178,0,0,0,114,166,0,0,0,114,105,0,0, + 0,114,189,0,0,0,114,104,0,0,0,41,10,114,17,0, + 0,0,114,164,0,0,0,114,165,0,0,0,114,190,0,0, + 0,90,9,105,115,95,114,101,108,111,97,100,114,188,0,0, + 0,114,166,0,0,0,114,94,0,0,0,114,95,0,0,0, + 114,104,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,10,95,102,105,110,100,95,115,112,101,99, + 124,3,0,0,115,54,0,0,0,0,2,6,1,8,2,8, + 3,4,1,12,5,10,1,8,1,8,1,2,1,10,1,14, + 1,12,1,8,1,22,2,42,1,8,2,18,1,10,1,2, + 1,10,1,14,4,14,2,10,1,8,2,10,2,10,2,114, + 194,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,5,0,0,0,67,0,0,0,115,108,0, + 0,0,116,0,124,0,116,1,131,2,115,28,116,2,100,1, + 160,3,116,4,124,0,131,1,161,1,131,1,130,1,124,2, + 100,2,107,0,114,44,116,5,100,3,131,1,130,1,124,2, + 100,2,107,4,114,84,116,0,124,1,116,1,131,2,115,72, + 116,2,100,4,131,1,130,1,110,12,124,1,115,84,116,6, + 100,5,131,1,130,1,124,0,115,104,124,2,100,2,107,2, + 114,104,116,5,100,6,131,1,130,1,100,7,83,0,41,8, + 122,28,86,101,114,105,102,121,32,97,114,103,117,109,101,110, + 116,115,32,97,114,101,32,34,115,97,110,101,34,46,122,31, + 109,111,100,117,108,101,32,110,97,109,101,32,109,117,115,116, + 32,98,101,32,115,116,114,44,32,110,111,116,32,123,125,114, + 22,0,0,0,122,18,108,101,118,101,108,32,109,117,115,116, + 32,98,101,32,62,61,32,48,122,31,95,95,112,97,99,107, + 97,103,101,95,95,32,110,111,116,32,115,101,116,32,116,111, + 32,97,32,115,116,114,105,110,103,122,54,97,116,116,101,109, + 112,116,101,100,32,114,101,108,97,116,105,118,101,32,105,109, + 112,111,114,116,32,119,105,116,104,32,110,111,32,107,110,111, + 119,110,32,112,97,114,101,110,116,32,112,97,99,107,97,103, + 101,122,17,69,109,112,116,121,32,109,111,100,117,108,101,32, + 110,97,109,101,78,41,7,218,10,105,115,105,110,115,116,97, + 110,99,101,218,3,115,116,114,218,9,84,121,112,101,69,114, + 114,111,114,114,44,0,0,0,114,14,0,0,0,218,10,86, + 97,108,117,101,69,114,114,111,114,114,78,0,0,0,169,3, + 114,17,0,0,0,114,185,0,0,0,114,186,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,13, + 95,115,97,110,105,116,121,95,99,104,101,99,107,171,3,0, + 0,115,22,0,0,0,0,2,10,1,18,1,8,1,8,1, + 8,1,10,1,10,1,4,1,8,2,12,1,114,200,0,0, + 0,122,16,78,111,32,109,111,100,117,108,101,32,110,97,109, + 101,100,32,122,4,123,33,114,125,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,220,0,0,0,100,0,125,2,124,0,160,0,100, + 1,161,1,100,2,25,0,125,3,124,3,114,134,124,3,116, + 1,106,2,107,7,114,42,116,3,124,1,124,3,131,2,1, + 0,124,0,116,1,106,2,107,6,114,62,116,1,106,2,124, + 0,25,0,83,0,116,1,106,2,124,3,25,0,125,4,122, + 10,124,4,106,4,125,2,87,0,110,50,4,0,116,5,107, + 10,114,132,1,0,1,0,1,0,116,6,100,3,23,0,160, + 7,124,0,124,3,161,2,125,5,116,8,124,5,124,0,100, + 4,141,2,100,0,130,2,89,0,110,2,48,0,116,9,124, + 0,124,2,131,2,125,6,124,6,100,0,107,8,114,172,116, + 8,116,6,160,7,124,0,161,1,124,0,100,4,141,2,130, + 1,110,8,116,10,124,6,131,1,125,7,124,3,114,216,116, + 1,106,2,124,3,25,0,125,4,116,11,124,4,124,0,160, + 0,100,1,161,1,100,5,25,0,124,7,131,3,1,0,124, + 7,83,0,41,6,78,114,127,0,0,0,114,22,0,0,0, + 122,23,59,32,123,33,114,125,32,105,115,32,110,111,116,32, + 97,32,112,97,99,107,97,103,101,114,16,0,0,0,233,2, + 0,0,0,41,12,114,128,0,0,0,114,15,0,0,0,114, + 91,0,0,0,114,66,0,0,0,114,140,0,0,0,114,105, + 0,0,0,218,8,95,69,82,82,95,77,83,71,114,44,0, + 0,0,218,19,77,111,100,117,108,101,78,111,116,70,111,117, + 110,100,69,114,114,111,114,114,194,0,0,0,114,158,0,0, + 0,114,5,0,0,0,41,8,114,17,0,0,0,218,7,105, + 109,112,111,114,116,95,114,164,0,0,0,114,129,0,0,0, + 90,13,112,97,114,101,110,116,95,109,111,100,117,108,101,114, + 156,0,0,0,114,94,0,0,0,114,95,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,218,23,95, + 102,105,110,100,95,97,110,100,95,108,111,97,100,95,117,110, + 108,111,99,107,101,100,190,3,0,0,115,42,0,0,0,0, + 1,4,1,14,1,4,1,10,1,10,2,10,1,10,1,10, + 1,2,1,10,1,14,1,16,1,20,1,10,1,8,1,20, + 2,8,1,4,2,10,1,22,1,114,205,0,0,0,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,128,0,0,0,116,0,124,0, + 131,1,143,62,1,0,116,1,106,2,160,3,124,0,116,4, + 161,2,125,2,124,2,116,4,107,8,114,56,116,5,124,0, + 124,1,131,2,87,0,2,0,100,1,4,0,4,0,131,3, + 1,0,83,0,87,0,100,1,4,0,4,0,131,3,1,0, + 110,16,49,0,115,76,48,0,1,0,1,0,1,0,89,0, + 1,0,124,2,100,1,107,8,114,116,100,2,160,6,124,0, + 161,1,125,3,116,7,124,3,124,0,100,3,141,2,130,1, + 116,8,124,0,131,1,1,0,124,2,83,0,41,4,122,25, + 70,105,110,100,32,97,110,100,32,108,111,97,100,32,116,104, + 101,32,109,111,100,117,108,101,46,78,122,40,105,109,112,111, + 114,116,32,111,102,32,123,125,32,104,97,108,116,101,100,59, + 32,78,111,110,101,32,105,110,32,115,121,115,46,109,111,100, + 117,108,101,115,114,16,0,0,0,41,9,114,49,0,0,0, + 114,15,0,0,0,114,91,0,0,0,114,34,0,0,0,218, + 14,95,78,69,69,68,83,95,76,79,65,68,73,78,71,114, + 205,0,0,0,114,44,0,0,0,114,203,0,0,0,114,64, + 0,0,0,41,4,114,17,0,0,0,114,204,0,0,0,114, + 95,0,0,0,114,74,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,14,95,102,105,110,100,95, + 97,110,100,95,108,111,97,100,220,3,0,0,115,22,0,0, + 0,0,2,10,1,14,1,8,1,54,2,8,1,4,1,2, + 255,4,2,12,2,8,1,114,207,0,0,0,114,22,0,0, + 0,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,42,0,0,0,116, + 0,124,0,124,1,124,2,131,3,1,0,124,2,100,1,107, + 4,114,32,116,1,124,0,124,1,124,2,131,3,125,0,116, + 2,124,0,116,3,131,2,83,0,41,2,97,50,1,0,0, + 73,109,112,111,114,116,32,97,110,100,32,114,101,116,117,114, + 110,32,116,104,101,32,109,111,100,117,108,101,32,98,97,115, + 101,100,32,111,110,32,105,116,115,32,110,97,109,101,44,32, + 116,104,101,32,112,97,99,107,97,103,101,32,116,104,101,32, + 99,97,108,108,32,105,115,10,32,32,32,32,98,101,105,110, + 103,32,109,97,100,101,32,102,114,111,109,44,32,97,110,100, + 32,116,104,101,32,108,101,118,101,108,32,97,100,106,117,115, + 116,109,101,110,116,46,10,10,32,32,32,32,84,104,105,115, + 32,102,117,110,99,116,105,111,110,32,114,101,112,114,101,115, + 101,110,116,115,32,116,104,101,32,103,114,101,97,116,101,115, + 116,32,99,111,109,109,111,110,32,100,101,110,111,109,105,110, + 97,116,111,114,32,111,102,32,102,117,110,99,116,105,111,110, + 97,108,105,116,121,10,32,32,32,32,98,101,116,119,101,101, + 110,32,105,109,112,111,114,116,95,109,111,100,117,108,101,32, + 97,110,100,32,95,95,105,109,112,111,114,116,95,95,46,32, + 84,104,105,115,32,105,110,99,108,117,100,101,115,32,115,101, + 116,116,105,110,103,32,95,95,112,97,99,107,97,103,101,95, + 95,32,105,102,10,32,32,32,32,116,104,101,32,108,111,97, + 100,101,114,32,100,105,100,32,110,111,116,46,10,10,32,32, + 32,32,114,22,0,0,0,41,4,114,200,0,0,0,114,187, + 0,0,0,114,207,0,0,0,218,11,95,103,99,100,95,105, + 109,112,111,114,116,114,199,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,208,0,0,0,236,3, + 0,0,115,8,0,0,0,0,9,12,1,8,1,12,1,114, + 208,0,0,0,169,1,218,9,114,101,99,117,114,115,105,118, + 101,99,3,0,0,0,0,0,0,0,1,0,0,0,8,0, + 0,0,11,0,0,0,67,0,0,0,115,234,0,0,0,124, + 1,68,0,93,224,125,4,116,0,124,4,116,1,131,2,115, + 66,124,3,114,34,124,0,106,2,100,1,23,0,125,5,110, + 4,100,2,125,5,116,3,100,3,124,5,155,0,100,4,116, + 4,124,4,131,1,106,2,155,0,157,4,131,1,130,1,113, + 4,124,4,100,5,107,2,114,108,124,3,115,228,116,5,124, + 0,100,6,131,2,114,228,116,6,124,0,124,0,106,7,124, + 2,100,7,100,8,141,4,1,0,113,4,116,5,124,0,124, + 4,131,2,115,4,100,9,160,8,124,0,106,2,124,4,161, + 2,125,6,122,14,116,9,124,2,124,6,131,2,1,0,87, + 0,113,4,4,0,116,10,107,10,114,226,1,0,125,7,1, + 0,122,54,124,7,106,11,124,6,107,2,114,204,116,12,106, + 13,160,14,124,6,116,15,161,2,100,10,107,9,114,204,87, + 0,89,0,100,10,125,7,126,7,113,4,130,0,87,0,89, + 0,100,10,125,7,126,7,113,4,100,10,125,7,126,7,48, + 0,48,0,113,4,124,0,83,0,41,11,122,238,70,105,103, + 117,114,101,32,111,117,116,32,119,104,97,116,32,95,95,105, + 109,112,111,114,116,95,95,32,115,104,111,117,108,100,32,114, + 101,116,117,114,110,46,10,10,32,32,32,32,84,104,101,32, + 105,109,112,111,114,116,95,32,112,97,114,97,109,101,116,101, + 114,32,105,115,32,97,32,99,97,108,108,97,98,108,101,32, + 119,104,105,99,104,32,116,97,107,101,115,32,116,104,101,32, + 110,97,109,101,32,111,102,32,109,111,100,117,108,101,32,116, + 111,10,32,32,32,32,105,109,112,111,114,116,46,32,73,116, + 32,105,115,32,114,101,113,117,105,114,101,100,32,116,111,32, + 100,101,99,111,117,112,108,101,32,116,104,101,32,102,117,110, + 99,116,105,111,110,32,102,114,111,109,32,97,115,115,117,109, + 105,110,103,32,105,109,112,111,114,116,108,105,98,39,115,10, + 32,32,32,32,105,109,112,111,114,116,32,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,32,105,115,32,100,101,115, + 105,114,101,100,46,10,10,32,32,32,32,122,8,46,95,95, + 97,108,108,95,95,122,13,96,96,102,114,111,109,32,108,105, + 115,116,39,39,122,8,73,116,101,109,32,105,110,32,122,18, + 32,109,117,115,116,32,98,101,32,115,116,114,44,32,110,111, + 116,32,250,1,42,218,7,95,95,97,108,108,95,95,84,114, + 209,0,0,0,114,182,0,0,0,78,41,16,114,195,0,0, + 0,114,196,0,0,0,114,1,0,0,0,114,197,0,0,0, + 114,14,0,0,0,114,4,0,0,0,218,16,95,104,97,110, + 100,108,101,95,102,114,111,109,108,105,115,116,114,212,0,0, + 0,114,44,0,0,0,114,66,0,0,0,114,203,0,0,0, + 114,17,0,0,0,114,15,0,0,0,114,91,0,0,0,114, + 34,0,0,0,114,206,0,0,0,41,8,114,95,0,0,0, + 218,8,102,114,111,109,108,105,115,116,114,204,0,0,0,114, + 210,0,0,0,218,1,120,90,5,119,104,101,114,101,90,9, + 102,114,111,109,95,110,97,109,101,90,3,101,120,99,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,213,0, + 0,0,251,3,0,0,115,44,0,0,0,0,10,8,1,10, + 1,4,1,12,2,4,1,28,2,8,1,14,1,10,1,2, + 255,8,2,10,1,14,1,2,1,14,1,16,4,10,1,16, + 255,2,2,12,1,26,1,114,213,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,6,0,0, + 0,67,0,0,0,115,146,0,0,0,124,0,160,0,100,1, + 161,1,125,1,124,0,160,0,100,2,161,1,125,2,124,1, + 100,3,107,9,114,82,124,2,100,3,107,9,114,78,124,1, + 124,2,106,1,107,3,114,78,116,2,106,3,100,4,124,1, + 155,2,100,5,124,2,106,1,155,2,100,6,157,5,116,4, + 100,7,100,8,141,3,1,0,124,1,83,0,124,2,100,3, + 107,9,114,96,124,2,106,1,83,0,116,2,106,3,100,9, + 116,4,100,7,100,8,141,3,1,0,124,0,100,10,25,0, + 125,1,100,11,124,0,107,7,114,142,124,1,160,5,100,12, + 161,1,100,13,25,0,125,1,124,1,83,0,41,14,122,167, + 67,97,108,99,117,108,97,116,101,32,119,104,97,116,32,95, + 95,112,97,99,107,97,103,101,95,95,32,115,104,111,117,108, + 100,32,98,101,46,10,10,32,32,32,32,95,95,112,97,99, + 107,97,103,101,95,95,32,105,115,32,110,111,116,32,103,117, + 97,114,97,110,116,101,101,100,32,116,111,32,98,101,32,100, + 101,102,105,110,101,100,32,111,114,32,99,111,117,108,100,32, + 98,101,32,115,101,116,32,116,111,32,78,111,110,101,10,32, + 32,32,32,116,111,32,114,101,112,114,101,115,101,110,116,32, + 116,104,97,116,32,105,116,115,32,112,114,111,112,101,114,32, + 118,97,108,117,101,32,105,115,32,117,110,107,110,111,119,110, + 46,10,10,32,32,32,32,114,144,0,0,0,114,104,0,0, + 0,78,122,32,95,95,112,97,99,107,97,103,101,95,95,32, + 33,61,32,95,95,115,112,101,99,95,95,46,112,97,114,101, + 110,116,32,40,122,4,32,33,61,32,250,1,41,233,3,0, + 0,0,41,1,90,10,115,116,97,99,107,108,101,118,101,108, + 122,89,99,97,110,39,116,32,114,101,115,111,108,118,101,32, + 112,97,99,107,97,103,101,32,102,114,111,109,32,95,95,115, + 112,101,99,95,95,32,111,114,32,95,95,112,97,99,107,97, + 103,101,95,95,44,32,102,97,108,108,105,110,103,32,98,97, + 99,107,32,111,110,32,95,95,110,97,109,101,95,95,32,97, + 110,100,32,95,95,112,97,116,104,95,95,114,1,0,0,0, + 114,140,0,0,0,114,127,0,0,0,114,22,0,0,0,41, + 6,114,34,0,0,0,114,129,0,0,0,114,191,0,0,0, + 114,192,0,0,0,114,193,0,0,0,114,128,0,0,0,41, + 3,218,7,103,108,111,98,97,108,115,114,185,0,0,0,114, + 94,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, + 107,97,103,101,95,95,32,4,0,0,115,38,0,0,0,0, + 7,10,1,10,1,8,1,18,1,22,2,2,0,2,254,6, + 3,4,1,8,1,6,2,6,2,2,0,2,254,6,3,8, + 1,8,1,14,1,114,219,0,0,0,114,10,0,0,0,99, + 5,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0, + 5,0,0,0,67,0,0,0,115,180,0,0,0,124,4,100, + 1,107,2,114,18,116,0,124,0,131,1,125,5,110,36,124, + 1,100,2,107,9,114,30,124,1,110,2,105,0,125,6,116, + 1,124,6,131,1,125,7,116,0,124,0,124,7,124,4,131, + 3,125,5,124,3,115,150,124,4,100,1,107,2,114,84,116, + 0,124,0,160,2,100,3,161,1,100,1,25,0,131,1,83, + 0,124,0,115,92,124,5,83,0,116,3,124,0,131,1,116, + 3,124,0,160,2,100,3,161,1,100,1,25,0,131,1,24, + 0,125,8,116,4,106,5,124,5,106,6,100,2,116,3,124, + 5,106,6,131,1,124,8,24,0,133,2,25,0,25,0,83, + 0,110,26,116,7,124,5,100,4,131,2,114,172,116,8,124, + 5,124,3,116,0,131,3,83,0,124,5,83,0,100,2,83, + 0,41,5,97,215,1,0,0,73,109,112,111,114,116,32,97, + 32,109,111,100,117,108,101,46,10,10,32,32,32,32,84,104, + 101,32,39,103,108,111,98,97,108,115,39,32,97,114,103,117, + 109,101,110,116,32,105,115,32,117,115,101,100,32,116,111,32, + 105,110,102,101,114,32,119,104,101,114,101,32,116,104,101,32, + 105,109,112,111,114,116,32,105,115,32,111,99,99,117,114,114, + 105,110,103,32,102,114,111,109,10,32,32,32,32,116,111,32, + 104,97,110,100,108,101,32,114,101,108,97,116,105,118,101,32, + 105,109,112,111,114,116,115,46,32,84,104,101,32,39,108,111, + 99,97,108,115,39,32,97,114,103,117,109,101,110,116,32,105, + 115,32,105,103,110,111,114,101,100,46,32,84,104,101,10,32, + 32,32,32,39,102,114,111,109,108,105,115,116,39,32,97,114, + 103,117,109,101,110,116,32,115,112,101,99,105,102,105,101,115, + 32,119,104,97,116,32,115,104,111,117,108,100,32,101,120,105, + 115,116,32,97,115,32,97,116,116,114,105,98,117,116,101,115, + 32,111,110,32,116,104,101,32,109,111,100,117,108,101,10,32, + 32,32,32,98,101,105,110,103,32,105,109,112,111,114,116,101, + 100,32,40,101,46,103,46,32,96,96,102,114,111,109,32,109, + 111,100,117,108,101,32,105,109,112,111,114,116,32,60,102,114, + 111,109,108,105,115,116,62,96,96,41,46,32,32,84,104,101, + 32,39,108,101,118,101,108,39,10,32,32,32,32,97,114,103, + 117,109,101,110,116,32,114,101,112,114,101,115,101,110,116,115, + 32,116,104,101,32,112,97,99,107,97,103,101,32,108,111,99, + 97,116,105,111,110,32,116,111,32,105,109,112,111,114,116,32, + 102,114,111,109,32,105,110,32,97,32,114,101,108,97,116,105, + 118,101,10,32,32,32,32,105,109,112,111,114,116,32,40,101, + 46,103,46,32,96,96,102,114,111,109,32,46,46,112,107,103, + 32,105,109,112,111,114,116,32,109,111,100,96,96,32,119,111, + 117,108,100,32,104,97,118,101,32,97,32,39,108,101,118,101, + 108,39,32,111,102,32,50,41,46,10,10,32,32,32,32,114, + 22,0,0,0,78,114,127,0,0,0,114,140,0,0,0,41, + 9,114,208,0,0,0,114,219,0,0,0,218,9,112,97,114, + 116,105,116,105,111,110,114,184,0,0,0,114,15,0,0,0, + 114,91,0,0,0,114,1,0,0,0,114,4,0,0,0,114, + 213,0,0,0,41,9,114,17,0,0,0,114,218,0,0,0, + 218,6,108,111,99,97,108,115,114,214,0,0,0,114,186,0, + 0,0,114,95,0,0,0,90,8,103,108,111,98,97,108,115, + 95,114,185,0,0,0,90,7,99,117,116,95,111,102,102,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,10, + 95,95,105,109,112,111,114,116,95,95,59,4,0,0,115,30, + 0,0,0,0,11,8,1,10,2,16,1,8,1,12,1,4, + 3,8,1,18,1,4,1,4,4,26,3,32,1,10,1,12, + 2,114,222,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, + 38,0,0,0,116,0,160,1,124,0,161,1,125,1,124,1, + 100,0,107,8,114,30,116,2,100,1,124,0,23,0,131,1, + 130,1,116,3,124,1,131,1,83,0,41,2,78,122,25,110, + 111,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,32,110,97,109,101,100,32,41,4,114,159,0,0,0,114, + 166,0,0,0,114,78,0,0,0,114,158,0,0,0,41,2, + 114,17,0,0,0,114,94,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,18,95,98,117,105,108, + 116,105,110,95,102,114,111,109,95,110,97,109,101,96,4,0, + 0,115,8,0,0,0,0,1,10,1,8,1,12,1,114,223, + 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, + 10,0,0,0,5,0,0,0,67,0,0,0,115,166,0,0, + 0,124,1,97,0,124,0,97,1,116,2,116,1,131,1,125, + 2,116,1,106,3,160,4,161,0,68,0,93,72,92,2,125, + 3,125,4,116,5,124,4,124,2,131,2,114,26,124,3,116, + 1,106,6,107,6,114,60,116,7,125,5,110,18,116,0,160, + 8,124,3,161,1,114,26,116,9,125,5,110,2,113,26,116, + 10,124,4,124,5,131,2,125,6,116,11,124,6,124,4,131, + 2,1,0,113,26,116,1,106,3,116,12,25,0,125,7,100, + 1,68,0,93,46,125,8,124,8,116,1,106,3,107,7,114, + 138,116,13,124,8,131,1,125,9,110,10,116,1,106,3,124, + 8,25,0,125,9,116,14,124,7,124,8,124,9,131,3,1, + 0,113,114,100,2,83,0,41,3,122,250,83,101,116,117,112, + 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,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,10,32,32,32,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,65,115,32,115,121,115,32,105,115, + 32,110,101,101,100,101,100,32,102,111,114,32,115,121,115,46, + 109,111,100,117,108,101,115,32,97,99,99,101,115,115,32,97, + 110,100,32,95,105,109,112,32,105,115,32,110,101,101,100,101, + 100,32,116,111,32,108,111,97,100,32,98,117,105,108,116,45, + 105,110,10,32,32,32,32,109,111,100,117,108,101,115,44,32, + 116,104,111,115,101,32,116,119,111,32,109,111,100,117,108,101, + 115,32,109,117,115,116,32,98,101,32,101,120,112,108,105,99, + 105,116,108,121,32,112,97,115,115,101,100,32,105,110,46,10, + 10,32,32,32,32,41,3,114,23,0,0,0,114,191,0,0, + 0,114,63,0,0,0,78,41,15,114,56,0,0,0,114,15, + 0,0,0,114,14,0,0,0,114,91,0,0,0,218,5,105, + 116,101,109,115,114,195,0,0,0,114,77,0,0,0,114,159, + 0,0,0,114,87,0,0,0,114,173,0,0,0,114,141,0, + 0,0,114,147,0,0,0,114,1,0,0,0,114,223,0,0, + 0,114,5,0,0,0,41,10,218,10,115,121,115,95,109,111, + 100,117,108,101,218,11,95,105,109,112,95,109,111,100,117,108, + 101,90,11,109,111,100,117,108,101,95,116,121,112,101,114,17, + 0,0,0,114,95,0,0,0,114,108,0,0,0,114,94,0, + 0,0,90,11,115,101,108,102,95,109,111,100,117,108,101,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,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,6,95,115, + 101,116,117,112,103,4,0,0,115,36,0,0,0,0,9,4, + 1,4,3,8,1,18,1,10,1,10,1,6,1,10,1,6, + 2,2,1,10,1,12,3,10,1,8,1,10,1,10,2,10, + 1,114,227,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, + 38,0,0,0,116,0,124,0,124,1,131,2,1,0,116,1, + 106,2,160,3,116,4,161,1,1,0,116,1,106,2,160,3, + 116,5,161,1,1,0,100,1,83,0,41,2,122,48,73,110, 115,116,97,108,108,32,105,109,112,111,114,116,101,114,115,32, - 116,104,97,116,32,114,101,113,117,105,114,101,32,101,120,116, - 101,114,110,97,108,32,102,105,108,101,115,121,115,116,101,109, - 32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218, - 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,125,0,0,0, - 114,228,0,0,0,114,15,0,0,0,114,91,0,0,0,114, - 1,0,0,0,41,1,114,229,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115, - 116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109, - 112,111,114,116,101,114,115,146,4,0,0,115,6,0,0,0, - 0,3,8,1,4,1,114,230,0,0,0,41,2,78,78,41, - 1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10, - 0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114, - 125,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59, - 0,0,0,114,33,0,0,0,114,42,0,0,0,114,19,0, - 0,0,114,20,0,0,0,114,48,0,0,0,114,49,0,0, - 0,114,52,0,0,0,114,64,0,0,0,114,66,0,0,0, - 114,75,0,0,0,114,85,0,0,0,114,89,0,0,0,114, - 96,0,0,0,114,110,0,0,0,114,111,0,0,0,114,90, - 0,0,0,114,141,0,0,0,114,147,0,0,0,114,151,0, - 0,0,114,106,0,0,0,114,92,0,0,0,114,157,0,0, - 0,114,158,0,0,0,114,93,0,0,0,114,159,0,0,0, - 114,173,0,0,0,114,178,0,0,0,114,187,0,0,0,114, - 189,0,0,0,114,194,0,0,0,114,200,0,0,0,90,15, - 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114, - 202,0,0,0,114,205,0,0,0,218,6,111,98,106,101,99, - 116,114,206,0,0,0,114,207,0,0,0,114,208,0,0,0, - 114,213,0,0,0,114,219,0,0,0,114,222,0,0,0,114, - 223,0,0,0,114,227,0,0,0,114,228,0,0,0,114,230, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,101, - 62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,8, - 8,8,4,2,4,3,16,4,14,68,14,21,14,16,8,37, - 8,17,8,11,14,8,8,11,8,12,8,16,8,36,14,101, - 16,26,10,45,14,72,8,17,8,17,8,30,8,37,8,42, - 8,15,14,75,14,79,14,13,8,9,8,9,10,47,8,16, - 4,1,8,2,8,27,6,3,8,16,10,15,14,37,8,27, - 10,37,8,7,8,35,8,8, + 102,111,114,32,98,117,105,108,116,105,110,32,97,110,100,32, + 102,114,111,122,101,110,32,109,111,100,117,108,101,115,78,41, + 6,114,227,0,0,0,114,15,0,0,0,114,190,0,0,0, + 114,118,0,0,0,114,159,0,0,0,114,173,0,0,0,41, + 2,114,225,0,0,0,114,226,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,8,95,105,110,115, + 116,97,108,108,138,4,0,0,115,6,0,0,0,0,2,10, + 2,12,1,114,228,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, + 0,115,32,0,0,0,100,1,100,2,108,0,125,0,124,0, + 97,1,124,0,160,2,116,3,106,4,116,5,25,0,161,1, + 1,0,100,2,83,0,41,3,122,57,73,110,115,116,97,108, + 108,32,105,109,112,111,114,116,101,114,115,32,116,104,97,116, + 32,114,101,113,117,105,114,101,32,101,120,116,101,114,110,97, + 108,32,102,105,108,101,115,121,115,116,101,109,32,97,99,99, + 101,115,115,114,22,0,0,0,78,41,6,218,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,125,0,0,0,114,228,0,0, + 0,114,15,0,0,0,114,91,0,0,0,114,1,0,0,0, + 41,1,114,229,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,27,95,105,110,115,116,97,108,108, + 95,101,120,116,101,114,110,97,108,95,105,109,112,111,114,116, + 101,114,115,146,4,0,0,115,6,0,0,0,0,3,8,1, + 4,1,114,230,0,0,0,41,2,78,78,41,1,78,41,2, + 78,114,22,0,0,0,41,4,78,78,114,10,0,0,0,114, + 22,0,0,0,41,50,114,3,0,0,0,114,125,0,0,0, + 114,12,0,0,0,114,18,0,0,0,114,58,0,0,0,114, + 33,0,0,0,114,42,0,0,0,114,19,0,0,0,114,20, + 0,0,0,114,48,0,0,0,114,49,0,0,0,114,52,0, + 0,0,114,64,0,0,0,114,66,0,0,0,114,75,0,0, + 0,114,85,0,0,0,114,89,0,0,0,114,96,0,0,0, + 114,110,0,0,0,114,111,0,0,0,114,90,0,0,0,114, + 141,0,0,0,114,147,0,0,0,114,151,0,0,0,114,106, + 0,0,0,114,92,0,0,0,114,157,0,0,0,114,158,0, + 0,0,114,93,0,0,0,114,159,0,0,0,114,173,0,0, + 0,114,178,0,0,0,114,187,0,0,0,114,189,0,0,0, + 114,194,0,0,0,114,200,0,0,0,90,15,95,69,82,82, + 95,77,83,71,95,80,82,69,70,73,88,114,202,0,0,0, + 114,205,0,0,0,218,6,111,98,106,101,99,116,114,206,0, + 0,0,114,207,0,0,0,114,208,0,0,0,114,213,0,0, + 0,114,219,0,0,0,114,222,0,0,0,114,223,0,0,0, + 114,227,0,0,0,114,228,0,0,0,114,230,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,8,60,109,111,100,117,108,101,62,1,0,0, + 0,115,94,0,0,0,4,24,4,2,8,8,8,8,4,2, + 4,3,16,4,14,68,14,21,14,16,8,37,8,17,8,11, + 14,8,8,11,8,12,8,16,8,36,14,101,16,26,10,45, + 14,72,8,17,8,17,8,30,8,37,8,42,8,15,14,75, + 14,79,14,13,8,9,8,9,10,47,8,16,4,1,8,2, + 8,27,6,3,8,16,10,15,14,37,8,27,10,37,8,7, + 8,35,8,8, }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 054fc84684522..8c1fa3cac8fa2 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -191,7 +191,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 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,50,0,0,0,122,12,116, 0,124,0,131,1,125,2,87,0,110,22,4,0,116,1,107, - 10,114,34,1,0,1,0,1,0,89,0,100,1,83,0,88, + 10,114,34,1,0,1,0,1,0,89,0,100,1,83,0,48, 0,124,2,106,2,100,2,64,0,124,1,107,2,83,0,41, 3,122,49,84,101,115,116,32,119,104,101,116,104,101,114,32, 116,104,101,32,112,97,116,104,32,105,115,32,116,104,101,32, @@ -242,2491 +242,2496 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 112,97,116,104,95,105,115,97,98,115,111,0,0,0,115,2, 0,0,0,0,6,114,58,0,0,0,233,182,1,0,0,99, 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, - 11,0,0,0,67,0,0,0,115,162,0,0,0,100,1,160, + 11,0,0,0,67,0,0,0,115,182,0,0,0,100,1,160, 0,124,0,116,1,124,0,131,1,161,2,125,3,116,2,160, 3,124,3,116,2,106,4,116,2,106,5,66,0,116,2,106, - 6,66,0,124,2,100,2,64,0,161,3,125,4,122,50,116, - 7,160,8,124,4,100,3,161,2,143,16,125,5,124,5,160, - 9,124,1,161,1,1,0,87,0,53,0,81,0,82,0,88, - 0,116,2,160,10,124,3,124,0,161,2,1,0,87,0,110, - 58,4,0,116,11,107,10,114,156,1,0,1,0,1,0,122, - 14,116,2,160,12,124,3,161,1,1,0,87,0,110,20,4, - 0,116,11,107,10,114,148,1,0,1,0,1,0,89,0,110, - 2,88,0,130,0,89,0,110,2,88,0,100,4,83,0,41, - 5,122,162,66,101,115,116,45,101,102,102,111,114,116,32,102, - 117,110,99,116,105,111,110,32,116,111,32,119,114,105,116,101, - 32,100,97,116,97,32,116,111,32,97,32,112,97,116,104,32, - 97,116,111,109,105,99,97,108,108,121,46,10,32,32,32,32, - 66,101,32,112,114,101,112,97,114,101,100,32,116,111,32,104, - 97,110,100,108,101,32,97,32,70,105,108,101,69,120,105,115, - 116,115,69,114,114,111,114,32,105,102,32,99,111,110,99,117, - 114,114,101,110,116,32,119,114,105,116,105,110,103,32,111,102, - 32,116,104,101,10,32,32,32,32,116,101,109,112,111,114,97, - 114,121,32,102,105,108,101,32,105,115,32,97,116,116,101,109, - 112,116,101,100,46,250,5,123,125,46,123,125,114,59,0,0, - 0,90,2,119,98,78,41,13,218,6,102,111,114,109,97,116, - 218,2,105,100,114,2,0,0,0,90,4,111,112,101,110,90, - 6,79,95,69,88,67,76,90,7,79,95,67,82,69,65,84, - 90,8,79,95,87,82,79,78,76,89,218,3,95,105,111,218, - 6,70,105,108,101,73,79,218,5,119,114,105,116,101,218,7, - 114,101,112,108,97,99,101,114,49,0,0,0,90,6,117,110, - 108,105,110,107,41,6,114,43,0,0,0,114,25,0,0,0, - 114,51,0,0,0,90,8,112,97,116,104,95,116,109,112,90, - 2,102,100,218,4,102,105,108,101,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,13,95,119,114,105,116,101, - 95,97,116,111,109,105,99,120,0,0,0,115,30,0,0,0, - 0,5,16,1,6,1,16,0,6,255,4,2,2,3,14,1, - 20,1,16,1,14,1,2,1,14,1,14,1,6,1,114,68, - 0,0,0,105,92,13,0,0,114,27,0,0,0,114,16,0, - 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, - 97,99,104,101,95,95,122,4,111,112,116,45,122,3,46,112, - 121,122,4,46,112,121,99,78,41,1,218,12,111,112,116,105, - 109,105,122,97,116,105,111,110,99,2,0,0,0,0,0,0, - 0,1,0,0,0,12,0,0,0,5,0,0,0,67,0,0, - 0,115,88,1,0,0,124,1,100,1,107,9,114,52,116,0, - 160,1,100,2,116,2,161,2,1,0,124,2,100,1,107,9, - 114,40,100,3,125,3,116,3,124,3,131,1,130,1,124,1, - 114,48,100,4,110,2,100,5,125,2,116,4,160,5,124,0, - 161,1,125,0,116,6,124,0,131,1,92,2,125,4,125,5, - 124,5,160,7,100,6,161,1,92,3,125,6,125,7,125,8, - 116,8,106,9,106,10,125,9,124,9,100,1,107,8,114,114, - 116,11,100,7,131,1,130,1,100,4,160,12,124,6,114,126, - 124,6,110,2,124,8,124,7,124,9,103,3,161,1,125,10, - 124,2,100,1,107,8,114,172,116,8,106,13,106,14,100,8, - 107,2,114,164,100,4,125,2,110,8,116,8,106,13,106,14, - 125,2,116,15,124,2,131,1,125,2,124,2,100,4,107,3, - 114,224,124,2,160,16,161,0,115,210,116,17,100,9,160,18, - 124,2,161,1,131,1,130,1,100,10,160,18,124,10,116,19, - 124,2,161,3,125,10,124,10,116,20,100,8,25,0,23,0, - 125,11,116,8,106,21,100,1,107,9,144,1,114,76,116,22, - 124,4,131,1,144,1,115,16,116,23,116,4,160,24,161,0, - 124,4,131,2,125,4,124,4,100,5,25,0,100,11,107,2, - 144,1,114,56,124,4,100,8,25,0,116,25,107,7,144,1, - 114,56,124,4,100,12,100,1,133,2,25,0,125,4,116,23, - 116,8,106,21,124,4,160,26,116,25,161,1,124,11,131,3, - 83,0,116,23,124,4,116,27,124,11,131,3,83,0,41,13, - 97,254,2,0,0,71,105,118,101,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,97,32,46,112,121,32,102,105,108, - 101,44,32,114,101,116,117,114,110,32,116,104,101,32,112,97, - 116,104,32,116,111,32,105,116,115,32,46,112,121,99,32,102, - 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112, - 121,32,102,105,108,101,32,100,111,101,115,32,110,111,116,32, - 110,101,101,100,32,116,111,32,101,120,105,115,116,59,32,116, - 104,105,115,32,115,105,109,112,108,121,32,114,101,116,117,114, - 110,115,32,116,104,101,32,112,97,116,104,32,116,111,32,116, - 104,101,10,32,32,32,32,46,112,121,99,32,102,105,108,101, - 32,99,97,108,99,117,108,97,116,101,100,32,97,115,32,105, - 102,32,116,104,101,32,46,112,121,32,102,105,108,101,32,119, - 101,114,101,32,105,109,112,111,114,116,101,100,46,10,10,32, - 32,32,32,84,104,101,32,39,111,112,116,105,109,105,122,97, - 116,105,111,110,39,32,112,97,114,97,109,101,116,101,114,32, - 99,111,110,116,114,111,108,115,32,116,104,101,32,112,114,101, - 115,117,109,101,100,32,111,112,116,105,109,105,122,97,116,105, - 111,110,32,108,101,118,101,108,32,111,102,10,32,32,32,32, - 116,104,101,32,98,121,116,101,99,111,100,101,32,102,105,108, - 101,46,32,73,102,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,105,115,32,110,111,116,32,78,111,110,101, - 44,32,116,104,101,32,115,116,114,105,110,103,32,114,101,112, - 114,101,115,101,110,116,97,116,105,111,110,10,32,32,32,32, - 111,102,32,116,104,101,32,97,114,103,117,109,101,110,116,32, - 105,115,32,116,97,107,101,110,32,97,110,100,32,118,101,114, - 105,102,105,101,100,32,116,111,32,98,101,32,97,108,112,104, - 97,110,117,109,101,114,105,99,32,40,101,108,115,101,32,86, - 97,108,117,101,69,114,114,111,114,10,32,32,32,32,105,115, - 32,114,97,105,115,101,100,41,46,10,10,32,32,32,32,84, - 104,101,32,100,101,98,117,103,95,111,118,101,114,114,105,100, - 101,32,112,97,114,97,109,101,116,101,114,32,105,115,32,100, - 101,112,114,101,99,97,116,101,100,46,32,73,102,32,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,105,115,32, - 110,111,116,32,78,111,110,101,44,10,32,32,32,32,97,32, - 84,114,117,101,32,118,97,108,117,101,32,105,115,32,116,104, - 101,32,115,97,109,101,32,97,115,32,115,101,116,116,105,110, - 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, - 32,116,111,32,116,104,101,32,101,109,112,116,121,32,115,116, - 114,105,110,103,10,32,32,32,32,119,104,105,108,101,32,97, - 32,70,97,108,115,101,32,118,97,108,117,101,32,105,115,32, - 101,113,117,105,118,97,108,101,110,116,32,116,111,32,115,101, + 6,66,0,124,2,100,2,64,0,161,3,125,4,122,70,116, + 7,160,8,124,4,100,3,161,2,143,26,125,5,124,5,160, + 9,124,1,161,1,1,0,87,0,100,4,4,0,4,0,131, + 3,1,0,110,16,49,0,115,94,48,0,1,0,1,0,1, + 0,89,0,1,0,116,2,160,10,124,3,124,0,161,2,1, + 0,87,0,110,58,4,0,116,11,107,10,114,176,1,0,1, + 0,1,0,122,14,116,2,160,12,124,3,161,1,1,0,87, + 0,110,20,4,0,116,11,107,10,114,168,1,0,1,0,1, + 0,89,0,110,2,48,0,130,0,89,0,110,2,48,0,100, + 4,83,0,41,5,122,162,66,101,115,116,45,101,102,102,111, + 114,116,32,102,117,110,99,116,105,111,110,32,116,111,32,119, + 114,105,116,101,32,100,97,116,97,32,116,111,32,97,32,112, + 97,116,104,32,97,116,111,109,105,99,97,108,108,121,46,10, + 32,32,32,32,66,101,32,112,114,101,112,97,114,101,100,32, + 116,111,32,104,97,110,100,108,101,32,97,32,70,105,108,101, + 69,120,105,115,116,115,69,114,114,111,114,32,105,102,32,99, + 111,110,99,117,114,114,101,110,116,32,119,114,105,116,105,110, + 103,32,111,102,32,116,104,101,10,32,32,32,32,116,101,109, + 112,111,114,97,114,121,32,102,105,108,101,32,105,115,32,97, + 116,116,101,109,112,116,101,100,46,250,5,123,125,46,123,125, + 114,59,0,0,0,90,2,119,98,78,41,13,218,6,102,111, + 114,109,97,116,218,2,105,100,114,2,0,0,0,90,4,111, + 112,101,110,90,6,79,95,69,88,67,76,90,7,79,95,67, + 82,69,65,84,90,8,79,95,87,82,79,78,76,89,218,3, + 95,105,111,218,6,70,105,108,101,73,79,218,5,119,114,105, + 116,101,218,7,114,101,112,108,97,99,101,114,49,0,0,0, + 90,6,117,110,108,105,110,107,41,6,114,43,0,0,0,114, + 25,0,0,0,114,51,0,0,0,90,8,112,97,116,104,95, + 116,109,112,90,2,102,100,218,4,102,105,108,101,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,119, + 114,105,116,101,95,97,116,111,109,105,99,120,0,0,0,115, + 30,0,0,0,0,5,16,1,6,1,16,0,6,255,4,2, + 2,3,14,1,40,1,16,1,14,1,2,1,14,1,14,1, + 6,1,114,68,0,0,0,105,94,13,0,0,114,27,0,0, + 0,114,16,0,0,0,115,2,0,0,0,13,10,90,11,95, + 95,112,121,99,97,99,104,101,95,95,122,4,111,112,116,45, + 122,3,46,112,121,122,4,46,112,121,99,78,41,1,218,12, + 111,112,116,105,109,105,122,97,116,105,111,110,99,2,0,0, + 0,0,0,0,0,1,0,0,0,12,0,0,0,5,0,0, + 0,67,0,0,0,115,88,1,0,0,124,1,100,1,107,9, + 114,52,116,0,160,1,100,2,116,2,161,2,1,0,124,2, + 100,1,107,9,114,40,100,3,125,3,116,3,124,3,131,1, + 130,1,124,1,114,48,100,4,110,2,100,5,125,2,116,4, + 160,5,124,0,161,1,125,0,116,6,124,0,131,1,92,2, + 125,4,125,5,124,5,160,7,100,6,161,1,92,3,125,6, + 125,7,125,8,116,8,106,9,106,10,125,9,124,9,100,1, + 107,8,114,114,116,11,100,7,131,1,130,1,100,4,160,12, + 124,6,114,126,124,6,110,2,124,8,124,7,124,9,103,3, + 161,1,125,10,124,2,100,1,107,8,114,172,116,8,106,13, + 106,14,100,8,107,2,114,164,100,4,125,2,110,8,116,8, + 106,13,106,14,125,2,116,15,124,2,131,1,125,2,124,2, + 100,4,107,3,114,224,124,2,160,16,161,0,115,210,116,17, + 100,9,160,18,124,2,161,1,131,1,130,1,100,10,160,18, + 124,10,116,19,124,2,161,3,125,10,124,10,116,20,100,8, + 25,0,23,0,125,11,116,8,106,21,100,1,107,9,144,1, + 114,76,116,22,124,4,131,1,144,1,115,16,116,23,116,4, + 160,24,161,0,124,4,131,2,125,4,124,4,100,5,25,0, + 100,11,107,2,144,1,114,56,124,4,100,8,25,0,116,25, + 107,7,144,1,114,56,124,4,100,12,100,1,133,2,25,0, + 125,4,116,23,116,8,106,21,124,4,160,26,116,25,161,1, + 124,11,131,3,83,0,116,23,124,4,116,27,124,11,131,3, + 83,0,41,13,97,254,2,0,0,71,105,118,101,110,32,116, + 104,101,32,112,97,116,104,32,116,111,32,97,32,46,112,121, + 32,102,105,108,101,44,32,114,101,116,117,114,110,32,116,104, + 101,32,112,97,116,104,32,116,111,32,105,116,115,32,46,112, + 121,99,32,102,105,108,101,46,10,10,32,32,32,32,84,104, + 101,32,46,112,121,32,102,105,108,101,32,100,111,101,115,32, + 110,111,116,32,110,101,101,100,32,116,111,32,101,120,105,115, + 116,59,32,116,104,105,115,32,115,105,109,112,108,121,32,114, + 101,116,117,114,110,115,32,116,104,101,32,112,97,116,104,32, + 116,111,32,116,104,101,10,32,32,32,32,46,112,121,99,32, + 102,105,108,101,32,99,97,108,99,117,108,97,116,101,100,32, + 97,115,32,105,102,32,116,104,101,32,46,112,121,32,102,105, + 108,101,32,119,101,114,101,32,105,109,112,111,114,116,101,100, + 46,10,10,32,32,32,32,84,104,101,32,39,111,112,116,105, + 109,105,122,97,116,105,111,110,39,32,112,97,114,97,109,101, + 116,101,114,32,99,111,110,116,114,111,108,115,32,116,104,101, + 32,112,114,101,115,117,109,101,100,32,111,112,116,105,109,105, + 122,97,116,105,111,110,32,108,101,118,101,108,32,111,102,10, + 32,32,32,32,116,104,101,32,98,121,116,101,99,111,100,101, + 32,102,105,108,101,46,32,73,102,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,115,32,110,111,116,32, + 78,111,110,101,44,32,116,104,101,32,115,116,114,105,110,103, + 32,114,101,112,114,101,115,101,110,116,97,116,105,111,110,10, + 32,32,32,32,111,102,32,116,104,101,32,97,114,103,117,109, + 101,110,116,32,105,115,32,116,97,107,101,110,32,97,110,100, + 32,118,101,114,105,102,105,101,100,32,116,111,32,98,101,32, + 97,108,112,104,97,110,117,109,101,114,105,99,32,40,101,108, + 115,101,32,86,97,108,117,101,69,114,114,111,114,10,32,32, + 32,32,105,115,32,114,97,105,115,101,100,41,46,10,10,32, + 32,32,32,84,104,101,32,100,101,98,117,103,95,111,118,101, + 114,114,105,100,101,32,112,97,114,97,109,101,116,101,114,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,73, + 102,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,105,115,32,110,111,116,32,78,111,110,101,44,10,32,32, + 32,32,97,32,84,114,117,101,32,118,97,108,117,101,32,105, + 115,32,116,104,101,32,115,97,109,101,32,97,115,32,115,101, 116,116,105,110,103,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,116,111,32,39,49,39,46,10,10,32,32, - 32,32,73,102,32,115,121,115,46,105,109,112,108,101,109,101, + 105,111,110,39,32,116,111,32,116,104,101,32,101,109,112,116, + 121,32,115,116,114,105,110,103,10,32,32,32,32,119,104,105, + 108,101,32,97,32,70,97,108,115,101,32,118,97,108,117,101, + 32,105,115,32,101,113,117,105,118,97,108,101,110,116,32,116, + 111,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,116,111,32,39,49,39,46, + 10,10,32,32,32,32,73,102,32,115,121,115,46,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,46,99,97,99,104, + 101,95,116,97,103,32,105,115,32,78,111,110,101,32,116,104, + 101,110,32,78,111,116,73,109,112,108,101,109,101,110,116,101, + 100,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 46,10,10,32,32,32,32,78,122,70,116,104,101,32,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,114, + 97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,59,32,117,115,101,32,39,111,112,116,105,109, + 105,122,97,116,105,111,110,39,32,105,110,115,116,101,97,100, + 122,50,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 32,111,114,32,111,112,116,105,109,105,122,97,116,105,111,110, + 32,109,117,115,116,32,98,101,32,115,101,116,32,116,111,32, + 78,111,110,101,114,39,0,0,0,114,38,0,0,0,218,1, + 46,250,36,115,121,115,46,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, + 105,115,32,78,111,110,101,233,0,0,0,0,122,24,123,33, + 114,125,32,105,115,32,110,111,116,32,97,108,112,104,97,110, + 117,109,101,114,105,99,122,7,123,125,46,123,125,123,125,250, + 1,58,114,27,0,0,0,41,28,218,9,95,119,97,114,110, + 105,110,103,115,218,4,119,97,114,110,218,18,68,101,112,114, + 101,99,97,116,105,111,110,87,97,114,110,105,110,103,218,9, + 84,121,112,101,69,114,114,111,114,114,2,0,0,0,218,6, + 102,115,112,97,116,104,114,46,0,0,0,114,40,0,0,0, + 114,8,0,0,0,218,14,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,103, + 218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,100, + 69,114,114,111,114,114,35,0,0,0,218,5,102,108,97,103, + 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, + 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, + 69,114,114,111,114,114,61,0,0,0,218,4,95,79,80,84, + 218,17,66,89,84,69,67,79,68,69,95,83,85,70,70,73, + 88,69,83,218,14,112,121,99,97,99,104,101,95,112,114,101, + 102,105,120,114,58,0,0,0,114,37,0,0,0,114,54,0, + 0,0,114,30,0,0,0,218,6,108,115,116,114,105,112,218, + 8,95,80,89,67,65,67,72,69,41,12,114,43,0,0,0, + 90,14,100,101,98,117,103,95,111,118,101,114,114,105,100,101, + 114,69,0,0,0,218,7,109,101,115,115,97,103,101,218,4, + 104,101,97,100,114,45,0,0,0,90,4,98,97,115,101,218, + 3,115,101,112,218,4,114,101,115,116,90,3,116,97,103,90, + 15,97,108,109,111,115,116,95,102,105,108,101,110,97,109,101, + 218,8,102,105,108,101,110,97,109,101,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,17,99,97,99,104,101, + 95,102,114,111,109,95,115,111,117,114,99,101,41,1,0,0, + 115,72,0,0,0,0,18,8,1,6,1,2,255,4,2,8, + 1,4,1,8,1,12,1,10,1,12,1,16,1,8,1,8, + 1,8,1,24,1,8,1,12,1,6,2,8,1,8,1,8, + 1,8,1,14,1,14,1,12,1,12,9,10,1,14,5,28, + 1,12,4,2,1,4,1,8,1,2,253,4,5,114,97,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,10, + 0,0,0,5,0,0,0,67,0,0,0,115,46,1,0,0, + 116,0,106,1,106,2,100,1,107,8,114,20,116,3,100,2, + 131,1,130,1,116,4,160,5,124,0,161,1,125,0,116,6, + 124,0,131,1,92,2,125,1,125,2,100,3,125,3,116,0, + 106,7,100,1,107,9,114,102,116,0,106,7,160,8,116,9, + 161,1,125,4,124,1,160,10,124,4,116,11,23,0,161,1, + 114,102,124,1,116,12,124,4,131,1,100,1,133,2,25,0, + 125,1,100,4,125,3,124,3,115,144,116,6,124,1,131,1, + 92,2,125,1,125,5,124,5,116,13,107,3,114,144,116,14, + 116,13,155,0,100,5,124,0,155,2,157,3,131,1,130,1, + 124,2,160,15,100,6,161,1,125,6,124,6,100,7,107,7, + 114,178,116,14,100,8,124,2,155,2,157,2,131,1,130,1, + 110,92,124,6,100,9,107,2,144,1,114,14,124,2,160,16, + 100,6,100,10,161,2,100,11,25,0,125,7,124,7,160,10, + 116,17,161,1,115,228,116,14,100,12,116,17,155,2,157,2, + 131,1,130,1,124,7,116,12,116,17,131,1,100,1,133,2, + 25,0,125,8,124,8,160,18,161,0,144,1,115,14,116,14, + 100,13,124,7,155,2,100,14,157,3,131,1,130,1,124,2, + 160,19,100,6,161,1,100,15,25,0,125,9,116,20,124,1, + 124,9,116,21,100,15,25,0,23,0,131,2,83,0,41,16, + 97,110,1,0,0,71,105,118,101,110,32,116,104,101,32,112, + 97,116,104,32,116,111,32,97,32,46,112,121,99,46,32,102, + 105,108,101,44,32,114,101,116,117,114,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,105,116,115,32,46,112,121,32, + 102,105,108,101,46,10,10,32,32,32,32,84,104,101,32,46, + 112,121,99,32,102,105,108,101,32,100,111,101,115,32,110,111, + 116,32,110,101,101,100,32,116,111,32,101,120,105,115,116,59, + 32,116,104,105,115,32,115,105,109,112,108,121,32,114,101,116, + 117,114,110,115,32,116,104,101,32,112,97,116,104,32,116,111, + 10,32,32,32,32,116,104,101,32,46,112,121,32,102,105,108, + 101,32,99,97,108,99,117,108,97,116,101,100,32,116,111,32, + 99,111,114,114,101,115,112,111,110,100,32,116,111,32,116,104, + 101,32,46,112,121,99,32,102,105,108,101,46,32,32,73,102, + 32,112,97,116,104,32,100,111,101,115,10,32,32,32,32,110, + 111,116,32,99,111,110,102,111,114,109,32,116,111,32,80,69, + 80,32,51,49,52,55,47,52,56,56,32,102,111,114,109,97, + 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, + 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, + 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,122,70,116,104,101,32,100,101,98,117,103,95, - 111,118,101,114,114,105,100,101,32,112,97,114,97,109,101,116, - 101,114,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 59,32,117,115,101,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,105,110,115,116,101,97,100,122,50,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,111,114,32, - 111,112,116,105,109,105,122,97,116,105,111,110,32,109,117,115, - 116,32,98,101,32,115,101,116,32,116,111,32,78,111,110,101, - 114,39,0,0,0,114,38,0,0,0,218,1,46,250,36,115, - 121,115,46,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,46,99,97,99,104,101,95,116,97,103,32,105,115,32,78, - 111,110,101,233,0,0,0,0,122,24,123,33,114,125,32,105, - 115,32,110,111,116,32,97,108,112,104,97,110,117,109,101,114, - 105,99,122,7,123,125,46,123,125,123,125,250,1,58,114,27, - 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, - 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, - 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, - 69,114,114,111,114,114,2,0,0,0,218,6,102,115,112,97, - 116,104,114,46,0,0,0,114,40,0,0,0,114,8,0,0, - 0,218,14,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,218,9,99,97,99,104,101,95,116,97,103,218,19,78,111, - 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, - 114,114,35,0,0,0,218,5,102,108,97,103,115,218,8,111, - 112,116,105,109,105,122,101,218,3,115,116,114,218,7,105,115, - 97,108,110,117,109,218,10,86,97,108,117,101,69,114,114,111, - 114,114,61,0,0,0,218,4,95,79,80,84,218,17,66,89, - 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,218, - 14,112,121,99,97,99,104,101,95,112,114,101,102,105,120,114, - 58,0,0,0,114,37,0,0,0,114,54,0,0,0,114,30, - 0,0,0,218,6,108,115,116,114,105,112,218,8,95,80,89, - 67,65,67,72,69,41,12,114,43,0,0,0,90,14,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,114,69,0,0, - 0,218,7,109,101,115,115,97,103,101,218,4,104,101,97,100, - 114,45,0,0,0,90,4,98,97,115,101,218,3,115,101,112, - 218,4,114,101,115,116,90,3,116,97,103,90,15,97,108,109, - 111,115,116,95,102,105,108,101,110,97,109,101,218,8,102,105, - 108,101,110,97,109,101,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,17,99,97,99,104,101,95,102,114,111, - 109,95,115,111,117,114,99,101,39,1,0,0,115,72,0,0, - 0,0,18,8,1,6,1,2,255,4,2,8,1,4,1,8, - 1,12,1,10,1,12,1,16,1,8,1,8,1,8,1,24, - 1,8,1,12,1,6,2,8,1,8,1,8,1,8,1,14, - 1,14,1,12,1,12,9,10,1,14,5,28,1,12,4,2, - 1,4,1,8,1,2,253,4,5,114,97,0,0,0,99,1, - 0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,5, - 0,0,0,67,0,0,0,115,46,1,0,0,116,0,106,1, - 106,2,100,1,107,8,114,20,116,3,100,2,131,1,130,1, - 116,4,160,5,124,0,161,1,125,0,116,6,124,0,131,1, - 92,2,125,1,125,2,100,3,125,3,116,0,106,7,100,1, - 107,9,114,102,116,0,106,7,160,8,116,9,161,1,125,4, - 124,1,160,10,124,4,116,11,23,0,161,1,114,102,124,1, - 116,12,124,4,131,1,100,1,133,2,25,0,125,1,100,4, - 125,3,124,3,115,144,116,6,124,1,131,1,92,2,125,1, - 125,5,124,5,116,13,107,3,114,144,116,14,116,13,155,0, - 100,5,124,0,155,2,157,3,131,1,130,1,124,2,160,15, - 100,6,161,1,125,6,124,6,100,7,107,7,114,178,116,14, - 100,8,124,2,155,2,157,2,131,1,130,1,110,92,124,6, - 100,9,107,2,144,1,114,14,124,2,160,16,100,6,100,10, - 161,2,100,11,25,0,125,7,124,7,160,10,116,17,161,1, - 115,228,116,14,100,12,116,17,155,2,157,2,131,1,130,1, - 124,7,116,12,116,17,131,1,100,1,133,2,25,0,125,8, - 124,8,160,18,161,0,144,1,115,14,116,14,100,13,124,7, - 155,2,100,14,157,3,131,1,130,1,124,2,160,19,100,6, - 161,1,100,15,25,0,125,9,116,20,124,1,124,9,116,21, - 100,15,25,0,23,0,131,2,83,0,41,16,97,110,1,0, - 0,71,105,118,101,110,32,116,104,101,32,112,97,116,104,32, - 116,111,32,97,32,46,112,121,99,46,32,102,105,108,101,44, - 32,114,101,116,117,114,110,32,116,104,101,32,112,97,116,104, - 32,116,111,32,105,116,115,32,46,112,121,32,102,105,108,101, - 46,10,10,32,32,32,32,84,104,101,32,46,112,121,99,32, - 102,105,108,101,32,100,111,101,115,32,110,111,116,32,110,101, - 101,100,32,116,111,32,101,120,105,115,116,59,32,116,104,105, - 115,32,115,105,109,112,108,121,32,114,101,116,117,114,110,115, - 32,116,104,101,32,112,97,116,104,32,116,111,10,32,32,32, - 32,116,104,101,32,46,112,121,32,102,105,108,101,32,99,97, - 108,99,117,108,97,116,101,100,32,116,111,32,99,111,114,114, - 101,115,112,111,110,100,32,116,111,32,116,104,101,32,46,112, - 121,99,32,102,105,108,101,46,32,32,73,102,32,112,97,116, - 104,32,100,111,101,115,10,32,32,32,32,110,111,116,32,99, - 111,110,102,111,114,109,32,116,111,32,80,69,80,32,51,49, - 52,55,47,52,56,56,32,102,111,114,109,97,116,44,32,86, - 97,108,117,101,69,114,114,111,114,32,119,105,108,108,32,98, - 101,32,114,97,105,115,101,100,46,32,73,102,10,32,32,32, - 32,115,121,115,46,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,46,99,97,99,104,101,95,116,97,103,32,105,115, - 32,78,111,110,101,32,116,104,101,110,32,78,111,116,73,109, - 112,108,101,109,101,110,116,101,100,69,114,114,111,114,32,105, - 115,32,114,97,105,115,101,100,46,10,10,32,32,32,32,78, - 114,71,0,0,0,70,84,122,31,32,110,111,116,32,98,111, - 116,116,111,109,45,108,101,118,101,108,32,100,105,114,101,99, - 116,111,114,121,32,105,110,32,114,70,0,0,0,62,2,0, - 0,0,114,27,0,0,0,114,56,0,0,0,122,29,101,120, - 112,101,99,116,101,100,32,111,110,108,121,32,50,32,111,114, - 32,51,32,100,111,116,115,32,105,110,32,114,56,0,0,0, - 114,27,0,0,0,233,254,255,255,255,122,53,111,112,116,105, - 109,105,122,97,116,105,111,110,32,112,111,114,116,105,111,110, - 32,111,102,32,102,105,108,101,110,97,109,101,32,100,111,101, - 115,32,110,111,116,32,115,116,97,114,116,32,119,105,116,104, - 32,122,19,111,112,116,105,109,105,122,97,116,105,111,110,32, - 108,101,118,101,108,32,122,29,32,105,115,32,110,111,116,32, - 97,110,32,97,108,112,104,97,110,117,109,101,114,105,99,32, - 118,97,108,117,101,114,72,0,0,0,41,22,114,8,0,0, - 0,114,79,0,0,0,114,80,0,0,0,114,81,0,0,0, - 114,2,0,0,0,114,78,0,0,0,114,46,0,0,0,114, - 89,0,0,0,114,29,0,0,0,114,30,0,0,0,114,10, - 0,0,0,114,34,0,0,0,114,22,0,0,0,114,91,0, - 0,0,114,86,0,0,0,218,5,99,111,117,110,116,114,42, - 0,0,0,114,87,0,0,0,114,85,0,0,0,218,9,112, - 97,114,116,105,116,105,111,110,114,37,0,0,0,218,15,83, - 79,85,82,67,69,95,83,85,70,70,73,88,69,83,41,10, - 114,43,0,0,0,114,93,0,0,0,90,16,112,121,99,97, - 99,104,101,95,102,105,108,101,110,97,109,101,90,23,102,111, - 117,110,100,95,105,110,95,112,121,99,97,99,104,101,95,112, - 114,101,102,105,120,90,13,115,116,114,105,112,112,101,100,95, - 112,97,116,104,90,7,112,121,99,97,99,104,101,90,9,100, - 111,116,95,99,111,117,110,116,114,69,0,0,0,90,9,111, - 112,116,95,108,101,118,101,108,90,13,98,97,115,101,95,102, - 105,108,101,110,97,109,101,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,17,115,111,117,114,99,101,95,102, - 114,111,109,95,99,97,99,104,101,110,1,0,0,115,52,0, - 0,0,0,9,12,1,8,1,10,1,12,1,4,1,10,1, - 12,1,14,1,16,1,4,1,4,1,12,1,8,1,18,2, - 10,1,8,1,16,1,10,1,16,1,10,1,14,2,16,1, - 10,1,16,2,14,1,114,102,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,9,0,0,0, - 67,0,0,0,115,126,0,0,0,116,0,124,0,131,1,100, - 1,107,2,114,16,100,2,83,0,124,0,160,1,100,3,161, - 1,92,3,125,1,125,2,125,3,124,1,114,56,124,3,160, - 2,161,0,100,4,100,5,133,2,25,0,100,6,107,3,114, - 60,124,0,83,0,122,12,116,3,124,0,131,1,125,4,87, - 0,110,36,4,0,116,4,116,5,102,2,107,10,114,108,1, - 0,1,0,1,0,124,0,100,2,100,5,133,2,25,0,125, - 4,89,0,110,2,88,0,116,6,124,4,131,1,114,122,124, - 4,83,0,124,0,83,0,41,7,122,188,67,111,110,118,101, - 114,116,32,97,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,32,112,97,116,104,32,116,111,32,97,32,115,111,117, - 114,99,101,32,112,97,116,104,32,40,105,102,32,112,111,115, - 115,105,98,108,101,41,46,10,10,32,32,32,32,84,104,105, - 115,32,102,117,110,99,116,105,111,110,32,101,120,105,115,116, - 115,32,112,117,114,101,108,121,32,102,111,114,32,98,97,99, - 107,119,97,114,100,115,45,99,111,109,112,97,116,105,98,105, - 108,105,116,121,32,102,111,114,10,32,32,32,32,80,121,73, - 109,112,111,114,116,95,69,120,101,99,67,111,100,101,77,111, - 100,117,108,101,87,105,116,104,70,105,108,101,110,97,109,101, - 115,40,41,32,105,110,32,116,104,101,32,67,32,65,80,73, - 46,10,10,32,32,32,32,114,72,0,0,0,78,114,70,0, - 0,0,233,253,255,255,255,233,255,255,255,255,90,2,112,121, - 41,7,114,22,0,0,0,114,40,0,0,0,218,5,108,111, - 119,101,114,114,102,0,0,0,114,81,0,0,0,114,86,0, - 0,0,114,53,0,0,0,41,5,218,13,98,121,116,101,99, - 111,100,101,95,112,97,116,104,114,95,0,0,0,114,44,0, - 0,0,90,9,101,120,116,101,110,115,105,111,110,218,11,115, - 111,117,114,99,101,95,112,97,116,104,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,15,95,103,101,116,95, - 115,111,117,114,99,101,102,105,108,101,150,1,0,0,115,20, - 0,0,0,0,7,12,1,4,1,16,1,24,1,4,1,2, - 1,12,1,18,1,18,1,114,108,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, - 0,67,0,0,0,115,74,0,0,0,124,0,160,0,116,1, - 116,2,131,1,161,1,114,48,122,10,116,3,124,0,131,1, - 87,0,83,0,4,0,116,4,107,10,114,44,1,0,1,0, - 1,0,89,0,113,70,88,0,110,22,124,0,160,0,116,1, - 116,5,131,1,161,1,114,66,124,0,83,0,100,0,83,0, - 100,0,83,0,169,1,78,41,6,218,8,101,110,100,115,119, - 105,116,104,218,5,116,117,112,108,101,114,101,0,0,0,114, - 97,0,0,0,114,81,0,0,0,114,88,0,0,0,41,1, - 114,96,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,11,95,103,101,116,95,99,97,99,104,101, - 100,169,1,0,0,115,16,0,0,0,0,1,14,1,2,1, - 10,1,14,1,8,1,14,1,4,2,114,112,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 8,0,0,0,67,0,0,0,115,52,0,0,0,122,14,116, - 0,124,0,131,1,106,1,125,1,87,0,110,24,4,0,116, - 2,107,10,114,38,1,0,1,0,1,0,100,1,125,1,89, - 0,110,2,88,0,124,1,100,2,79,0,125,1,124,1,83, - 0,41,3,122,51,67,97,108,99,117,108,97,116,101,32,116, - 104,101,32,109,111,100,101,32,112,101,114,109,105,115,115,105, - 111,110,115,32,102,111,114,32,97,32,98,121,116,101,99,111, - 100,101,32,102,105,108,101,46,114,59,0,0,0,233,128,0, - 0,0,41,3,114,48,0,0,0,114,50,0,0,0,114,49, - 0,0,0,41,2,114,43,0,0,0,114,51,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,10, - 95,99,97,108,99,95,109,111,100,101,181,1,0,0,115,12, - 0,0,0,0,2,2,1,14,1,14,1,10,3,8,1,114, - 114,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,3,0,0,0,8,0,0,0,3,0,0,0,115,68,0, - 0,0,100,6,135,0,102,1,100,2,100,3,132,9,125,1, - 122,10,116,0,106,1,125,2,87,0,110,28,4,0,116,2, - 107,10,114,52,1,0,1,0,1,0,100,4,100,5,132,0, - 125,2,89,0,110,2,88,0,124,2,124,1,136,0,131,2, - 1,0,124,1,83,0,41,7,122,252,68,101,99,111,114,97, - 116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,104, - 97,116,32,116,104,101,32,109,111,100,117,108,101,32,98,101, - 105,110,103,32,114,101,113,117,101,115,116,101,100,32,109,97, - 116,99,104,101,115,32,116,104,101,32,111,110,101,32,116,104, - 101,10,32,32,32,32,108,111,97,100,101,114,32,99,97,110, - 32,104,97,110,100,108,101,46,10,10,32,32,32,32,84,104, - 101,32,102,105,114,115,116,32,97,114,103,117,109,101,110,116, - 32,40,115,101,108,102,41,32,109,117,115,116,32,100,101,102, - 105,110,101,32,95,110,97,109,101,32,119,104,105,99,104,32, - 116,104,101,32,115,101,99,111,110,100,32,97,114,103,117,109, - 101,110,116,32,105,115,10,32,32,32,32,99,111,109,112,97, - 114,101,100,32,97,103,97,105,110,115,116,46,32,73,102,32, - 116,104,101,32,99,111,109,112,97,114,105,115,111,110,32,102, - 97,105,108,115,32,116,104,101,110,32,73,109,112,111,114,116, - 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,46, - 10,10,32,32,32,32,78,99,2,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,4,0,0,0,31,0,0,0, - 115,66,0,0,0,124,1,100,0,107,8,114,16,124,0,106, - 0,125,1,110,32,124,0,106,0,124,1,107,3,114,48,116, - 1,100,1,124,0,106,0,124,1,102,2,22,0,124,1,100, - 2,141,2,130,1,136,0,124,0,124,1,102,2,124,2,158, - 2,124,3,142,1,83,0,41,3,78,122,30,108,111,97,100, - 101,114,32,102,111,114,32,37,115,32,99,97,110,110,111,116, - 32,104,97,110,100,108,101,32,37,115,169,1,218,4,110,97, - 109,101,41,2,114,116,0,0,0,218,11,73,109,112,111,114, - 116,69,114,114,111,114,41,4,218,4,115,101,108,102,114,116, - 0,0,0,218,4,97,114,103,115,218,6,107,119,97,114,103, - 115,169,1,218,6,109,101,116,104,111,100,114,3,0,0,0, - 114,6,0,0,0,218,19,95,99,104,101,99,107,95,110,97, - 109,101,95,119,114,97,112,112,101,114,201,1,0,0,115,18, - 0,0,0,0,1,8,1,8,1,10,1,4,1,8,255,2, - 1,2,255,6,2,122,40,95,99,104,101,99,107,95,110,97, - 109,101,46,60,108,111,99,97,108,115,62,46,95,99,104,101, - 99,107,95,110,97,109,101,95,119,114,97,112,112,101,114,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 7,0,0,0,83,0,0,0,115,56,0,0,0,100,1,68, - 0,93,32,125,2,116,0,124,1,124,2,131,2,114,4,116, - 1,124,0,124,2,116,2,124,1,124,2,131,2,131,3,1, - 0,113,4,124,0,106,3,160,4,124,1,106,3,161,1,1, - 0,100,0,83,0,41,2,78,41,4,218,10,95,95,109,111, - 100,117,108,101,95,95,218,8,95,95,110,97,109,101,95,95, - 218,12,95,95,113,117,97,108,110,97,109,101,95,95,218,7, - 95,95,100,111,99,95,95,41,5,218,7,104,97,115,97,116, - 116,114,218,7,115,101,116,97,116,116,114,218,7,103,101,116, - 97,116,116,114,218,8,95,95,100,105,99,116,95,95,218,6, - 117,112,100,97,116,101,41,3,90,3,110,101,119,90,3,111, - 108,100,114,66,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,5,95,119,114,97,112,212,1,0, - 0,115,8,0,0,0,0,1,8,1,10,1,20,1,122,26, - 95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,99, - 97,108,115,62,46,95,119,114,97,112,41,1,78,41,3,218, - 10,95,98,111,111,116,115,116,114,97,112,114,133,0,0,0, - 218,9,78,97,109,101,69,114,114,111,114,41,3,114,122,0, - 0,0,114,123,0,0,0,114,133,0,0,0,114,3,0,0, - 0,114,121,0,0,0,114,6,0,0,0,218,11,95,99,104, - 101,99,107,95,110,97,109,101,193,1,0,0,115,14,0,0, - 0,0,8,14,7,2,1,10,1,14,2,14,5,10,1,114, - 136,0,0,0,99,2,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,6,0,0,0,67,0,0,0,115,60,0, - 0,0,124,0,160,0,124,1,161,1,92,2,125,2,125,3, - 124,2,100,1,107,8,114,56,116,1,124,3,131,1,114,56, - 100,2,125,4,116,2,160,3,124,4,160,4,124,3,100,3, - 25,0,161,1,116,5,161,2,1,0,124,2,83,0,41,4, - 122,155,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,32, - 98,121,32,100,101,108,101,103,97,116,105,110,103,32,116,111, - 10,32,32,32,32,115,101,108,102,46,102,105,110,100,95,108, - 111,97,100,101,114,40,41,46,10,10,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,32,105,110,32,102,97,118,111,114, - 32,111,102,32,102,105,110,100,101,114,46,102,105,110,100,95, - 115,112,101,99,40,41,46,10,10,32,32,32,32,78,122,44, - 78,111,116,32,105,109,112,111,114,116,105,110,103,32,100,105, - 114,101,99,116,111,114,121,32,123,125,58,32,109,105,115,115, - 105,110,103,32,95,95,105,110,105,116,95,95,114,72,0,0, - 0,41,6,218,11,102,105,110,100,95,108,111,97,100,101,114, - 114,22,0,0,0,114,74,0,0,0,114,75,0,0,0,114, - 61,0,0,0,218,13,73,109,112,111,114,116,87,97,114,110, - 105,110,103,41,5,114,118,0,0,0,218,8,102,117,108,108, - 110,97,109,101,218,6,108,111,97,100,101,114,218,8,112,111, - 114,116,105,111,110,115,218,3,109,115,103,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,17,95,102,105,110, - 100,95,109,111,100,117,108,101,95,115,104,105,109,221,1,0, - 0,115,10,0,0,0,0,10,14,1,16,1,4,1,22,1, - 114,143,0,0,0,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,158, - 0,0,0,124,0,100,1,100,2,133,2,25,0,125,3,124, - 3,116,0,107,3,114,60,100,3,124,1,155,2,100,4,124, - 3,155,2,157,4,125,4,116,1,160,2,100,5,124,4,161, - 2,1,0,116,3,124,4,102,1,124,2,142,1,130,1,116, - 4,124,0,131,1,100,6,107,0,114,102,100,7,124,1,155, - 2,157,2,125,4,116,1,160,2,100,5,124,4,161,2,1, - 0,116,5,124,4,131,1,130,1,116,6,124,0,100,2,100, - 8,133,2,25,0,131,1,125,5,124,5,100,9,64,0,114, - 154,100,10,124,5,155,2,100,11,124,1,155,2,157,4,125, - 4,116,3,124,4,102,1,124,2,142,1,130,1,124,5,83, - 0,41,12,97,84,2,0,0,80,101,114,102,111,114,109,32, - 98,97,115,105,99,32,118,97,108,105,100,105,116,121,32,99, - 104,101,99,107,105,110,103,32,111,102,32,97,32,112,121,99, - 32,104,101,97,100,101,114,32,97,110,100,32,114,101,116,117, - 114,110,32,116,104,101,32,102,108,97,103,115,32,102,105,101, - 108,100,44,10,32,32,32,32,119,104,105,99,104,32,100,101, - 116,101,114,109,105,110,101,115,32,104,111,119,32,116,104,101, - 32,112,121,99,32,115,104,111,117,108,100,32,98,101,32,102, - 117,114,116,104,101,114,32,118,97,108,105,100,97,116,101,100, - 32,97,103,97,105,110,115,116,32,116,104,101,32,115,111,117, - 114,99,101,46,10,10,32,32,32,32,42,100,97,116,97,42, - 32,105,115,32,116,104,101,32,99,111,110,116,101,110,116,115, - 32,111,102,32,116,104,101,32,112,121,99,32,102,105,108,101, - 46,32,40,79,110,108,121,32,116,104,101,32,102,105,114,115, - 116,32,49,54,32,98,121,116,101,115,32,97,114,101,10,32, - 32,32,32,114,101,113,117,105,114,101,100,44,32,116,104,111, - 117,103,104,46,41,10,10,32,32,32,32,42,110,97,109,101, - 42,32,105,115,32,116,104,101,32,110,97,109,101,32,111,102, - 32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,110, - 103,32,105,109,112,111,114,116,101,100,46,32,73,116,32,105, - 115,32,117,115,101,100,32,102,111,114,32,108,111,103,103,105, - 110,103,46,10,10,32,32,32,32,42,101,120,99,95,100,101, - 116,97,105,108,115,42,32,105,115,32,97,32,100,105,99,116, - 105,111,110,97,114,121,32,112,97,115,115,101,100,32,116,111, - 32,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, - 105,116,32,114,97,105,115,101,100,32,102,111,114,10,32,32, - 32,32,105,109,112,114,111,118,101,100,32,100,101,98,117,103, - 103,105,110,103,46,10,10,32,32,32,32,73,109,112,111,114, - 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 32,119,104,101,110,32,116,104,101,32,109,97,103,105,99,32, - 110,117,109,98,101,114,32,105,115,32,105,110,99,111,114,114, - 101,99,116,32,111,114,32,119,104,101,110,32,116,104,101,32, - 102,108,97,103,115,10,32,32,32,32,102,105,101,108,100,32, - 105,115,32,105,110,118,97,108,105,100,46,32,69,79,70,69, - 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,119, - 104,101,110,32,116,104,101,32,100,97,116,97,32,105,115,32, - 102,111,117,110,100,32,116,111,32,98,101,32,116,114,117,110, - 99,97,116,101,100,46,10,10,32,32,32,32,78,114,15,0, - 0,0,122,20,98,97,100,32,109,97,103,105,99,32,110,117, - 109,98,101,114,32,105,110,32,122,2,58,32,250,2,123,125, - 233,16,0,0,0,122,40,114,101,97,99,104,101,100,32,69, - 79,70,32,119,104,105,108,101,32,114,101,97,100,105,110,103, - 32,112,121,99,32,104,101,97,100,101,114,32,111,102,32,233, - 8,0,0,0,233,252,255,255,255,122,14,105,110,118,97,108, - 105,100,32,102,108,97,103,115,32,122,4,32,105,110,32,41, - 7,218,12,77,65,71,73,67,95,78,85,77,66,69,82,114, - 134,0,0,0,218,16,95,118,101,114,98,111,115,101,95,109, - 101,115,115,97,103,101,114,117,0,0,0,114,22,0,0,0, - 218,8,69,79,70,69,114,114,111,114,114,26,0,0,0,41, - 6,114,25,0,0,0,114,116,0,0,0,218,11,101,120,99, - 95,100,101,116,97,105,108,115,90,5,109,97,103,105,99,114, - 92,0,0,0,114,82,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,13,95,99,108,97,115,115, - 105,102,121,95,112,121,99,238,1,0,0,115,28,0,0,0, - 0,16,12,1,8,1,16,1,12,1,12,1,12,1,10,1, - 12,1,8,1,16,2,8,1,16,1,12,1,114,152,0,0, - 0,99,5,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,4,0,0,0,67,0,0,0,115,112,0,0,0,116, - 0,124,0,100,1,100,2,133,2,25,0,131,1,124,1,100, - 3,64,0,107,3,114,58,100,4,124,3,155,2,157,2,125, - 5,116,1,160,2,100,5,124,5,161,2,1,0,116,3,124, - 5,102,1,124,4,142,1,130,1,124,2,100,6,107,9,114, - 108,116,0,124,0,100,2,100,7,133,2,25,0,131,1,124, - 2,100,3,64,0,107,3,114,108,116,3,100,4,124,3,155, - 2,157,2,102,1,124,4,142,1,130,1,100,6,83,0,41, - 8,97,7,2,0,0,86,97,108,105,100,97,116,101,32,97, - 32,112,121,99,32,97,103,97,105,110,115,116,32,116,104,101, - 32,115,111,117,114,99,101,32,108,97,115,116,45,109,111,100, - 105,102,105,101,100,32,116,105,109,101,46,10,10,32,32,32, - 32,42,100,97,116,97,42,32,105,115,32,116,104,101,32,99, - 111,110,116,101,110,116,115,32,111,102,32,116,104,101,32,112, - 121,99,32,102,105,108,101,46,32,40,79,110,108,121,32,116, - 104,101,32,102,105,114,115,116,32,49,54,32,98,121,116,101, - 115,32,97,114,101,10,32,32,32,32,114,101,113,117,105,114, - 101,100,46,41,10,10,32,32,32,32,42,115,111,117,114,99, - 101,95,109,116,105,109,101,42,32,105,115,32,116,104,101,32, - 108,97,115,116,32,109,111,100,105,102,105,101,100,32,116,105, - 109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,115, - 111,117,114,99,101,32,102,105,108,101,46,10,10,32,32,32, - 32,42,115,111,117,114,99,101,95,115,105,122,101,42,32,105, - 115,32,78,111,110,101,32,111,114,32,116,104,101,32,115,105, - 122,101,32,111,102,32,116,104,101,32,115,111,117,114,99,101, - 32,102,105,108,101,32,105,110,32,98,121,116,101,115,46,10, - 10,32,32,32,32,42,110,97,109,101,42,32,105,115,32,116, - 104,101,32,110,97,109,101,32,111,102,32,116,104,101,32,109, - 111,100,117,108,101,32,98,101,105,110,103,32,105,109,112,111, - 114,116,101,100,46,32,73,116,32,105,115,32,117,115,101,100, - 32,102,111,114,32,108,111,103,103,105,110,103,46,10,10,32, - 32,32,32,42,101,120,99,95,100,101,116,97,105,108,115,42, - 32,105,115,32,97,32,100,105,99,116,105,111,110,97,114,121, - 32,112,97,115,115,101,100,32,116,111,32,73,109,112,111,114, - 116,69,114,114,111,114,32,105,102,32,105,116,32,114,97,105, - 115,101,100,32,102,111,114,10,32,32,32,32,105,109,112,114, - 111,118,101,100,32,100,101,98,117,103,103,105,110,103,46,10, - 10,32,32,32,32,65,110,32,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,116,104,101,32,98,121,116,101,99,111,100,101,32,105,115, - 32,115,116,97,108,101,46,10,10,32,32,32,32,114,146,0, - 0,0,233,12,0,0,0,114,14,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,114,144,0,0,0,78,114,145,0,0,0,41, - 4,114,26,0,0,0,114,134,0,0,0,114,149,0,0,0, - 114,117,0,0,0,41,6,114,25,0,0,0,218,12,115,111, - 117,114,99,101,95,109,116,105,109,101,218,11,115,111,117,114, - 99,101,95,115,105,122,101,114,116,0,0,0,114,151,0,0, - 0,114,92,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,23,95,118,97,108,105,100,97,116,101, - 95,116,105,109,101,115,116,97,109,112,95,112,121,99,15,2, - 0,0,115,16,0,0,0,0,19,24,1,10,1,12,1,12, - 1,8,1,22,255,2,2,114,156,0,0,0,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,38,0,0,0,124,0,100,1,100,2, - 133,2,25,0,124,1,107,3,114,34,116,0,100,3,124,2, - 155,2,157,2,102,1,124,3,142,1,130,1,100,4,83,0, - 41,5,97,243,1,0,0,86,97,108,105,100,97,116,101,32, - 97,32,104,97,115,104,45,98,97,115,101,100,32,112,121,99, - 32,98,121,32,99,104,101,99,107,105,110,103,32,116,104,101, - 32,114,101,97,108,32,115,111,117,114,99,101,32,104,97,115, - 104,32,97,103,97,105,110,115,116,32,116,104,101,32,111,110, - 101,32,105,110,10,32,32,32,32,116,104,101,32,112,121,99, - 32,104,101,97,100,101,114,46,10,10,32,32,32,32,42,100, + 32,32,32,78,114,71,0,0,0,70,84,122,31,32,110,111, + 116,32,98,111,116,116,111,109,45,108,101,118,101,108,32,100, + 105,114,101,99,116,111,114,121,32,105,110,32,114,70,0,0, + 0,62,2,0,0,0,114,27,0,0,0,114,56,0,0,0, + 122,29,101,120,112,101,99,116,101,100,32,111,110,108,121,32, + 50,32,111,114,32,51,32,100,111,116,115,32,105,110,32,114, + 56,0,0,0,114,27,0,0,0,233,254,255,255,255,122,53, + 111,112,116,105,109,105,122,97,116,105,111,110,32,112,111,114, + 116,105,111,110,32,111,102,32,102,105,108,101,110,97,109,101, + 32,100,111,101,115,32,110,111,116,32,115,116,97,114,116,32, + 119,105,116,104,32,122,19,111,112,116,105,109,105,122,97,116, + 105,111,110,32,108,101,118,101,108,32,122,29,32,105,115,32, + 110,111,116,32,97,110,32,97,108,112,104,97,110,117,109,101, + 114,105,99,32,118,97,108,117,101,114,72,0,0,0,41,22, + 114,8,0,0,0,114,79,0,0,0,114,80,0,0,0,114, + 81,0,0,0,114,2,0,0,0,114,78,0,0,0,114,46, + 0,0,0,114,89,0,0,0,114,29,0,0,0,114,30,0, + 0,0,114,10,0,0,0,114,34,0,0,0,114,22,0,0, + 0,114,91,0,0,0,114,86,0,0,0,218,5,99,111,117, + 110,116,114,42,0,0,0,114,87,0,0,0,114,85,0,0, + 0,218,9,112,97,114,116,105,116,105,111,110,114,37,0,0, + 0,218,15,83,79,85,82,67,69,95,83,85,70,70,73,88, + 69,83,41,10,114,43,0,0,0,114,93,0,0,0,90,16, + 112,121,99,97,99,104,101,95,102,105,108,101,110,97,109,101, + 90,23,102,111,117,110,100,95,105,110,95,112,121,99,97,99, + 104,101,95,112,114,101,102,105,120,90,13,115,116,114,105,112, + 112,101,100,95,112,97,116,104,90,7,112,121,99,97,99,104, + 101,90,9,100,111,116,95,99,111,117,110,116,114,69,0,0, + 0,90,9,111,112,116,95,108,101,118,101,108,90,13,98,97, + 115,101,95,102,105,108,101,110,97,109,101,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,115,111,117,114, + 99,101,95,102,114,111,109,95,99,97,99,104,101,112,1,0, + 0,115,52,0,0,0,0,9,12,1,8,1,10,1,12,1, + 4,1,10,1,12,1,14,1,16,1,4,1,4,1,12,1, + 8,1,18,2,10,1,8,1,16,1,10,1,16,1,10,1, + 14,2,16,1,10,1,16,2,14,1,114,102,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, + 9,0,0,0,67,0,0,0,115,126,0,0,0,116,0,124, + 0,131,1,100,1,107,2,114,16,100,2,83,0,124,0,160, + 1,100,3,161,1,92,3,125,1,125,2,125,3,124,1,114, + 56,124,3,160,2,161,0,100,4,100,5,133,2,25,0,100, + 6,107,3,114,60,124,0,83,0,122,12,116,3,124,0,131, + 1,125,4,87,0,110,36,4,0,116,4,116,5,102,2,107, + 10,114,108,1,0,1,0,1,0,124,0,100,2,100,5,133, + 2,25,0,125,4,89,0,110,2,48,0,116,6,124,4,131, + 1,114,122,124,4,83,0,124,0,83,0,41,7,122,188,67, + 111,110,118,101,114,116,32,97,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,32,112,97,116,104,32,116,111,32,97, + 32,115,111,117,114,99,101,32,112,97,116,104,32,40,105,102, + 32,112,111,115,115,105,98,108,101,41,46,10,10,32,32,32, + 32,84,104,105,115,32,102,117,110,99,116,105,111,110,32,101, + 120,105,115,116,115,32,112,117,114,101,108,121,32,102,111,114, + 32,98,97,99,107,119,97,114,100,115,45,99,111,109,112,97, + 116,105,98,105,108,105,116,121,32,102,111,114,10,32,32,32, + 32,80,121,73,109,112,111,114,116,95,69,120,101,99,67,111, + 100,101,77,111,100,117,108,101,87,105,116,104,70,105,108,101, + 110,97,109,101,115,40,41,32,105,110,32,116,104,101,32,67, + 32,65,80,73,46,10,10,32,32,32,32,114,72,0,0,0, + 78,114,70,0,0,0,233,253,255,255,255,233,255,255,255,255, + 90,2,112,121,41,7,114,22,0,0,0,114,40,0,0,0, + 218,5,108,111,119,101,114,114,102,0,0,0,114,81,0,0, + 0,114,86,0,0,0,114,53,0,0,0,41,5,218,13,98, + 121,116,101,99,111,100,101,95,112,97,116,104,114,95,0,0, + 0,114,44,0,0,0,90,9,101,120,116,101,110,115,105,111, + 110,218,11,115,111,117,114,99,101,95,112,97,116,104,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, + 103,101,116,95,115,111,117,114,99,101,102,105,108,101,152,1, + 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, + 1,4,1,2,1,12,1,18,1,18,1,114,108,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,8,0,0,0,67,0,0,0,115,74,0,0,0,124,0, + 160,0,116,1,116,2,131,1,161,1,114,48,122,10,116,3, + 124,0,131,1,87,0,83,0,4,0,116,4,107,10,114,44, + 1,0,1,0,1,0,89,0,113,70,48,0,110,22,124,0, + 160,0,116,1,116,5,131,1,161,1,114,66,124,0,83,0, + 100,0,83,0,100,0,83,0,169,1,78,41,6,218,8,101, + 110,100,115,119,105,116,104,218,5,116,117,112,108,101,114,101, + 0,0,0,114,97,0,0,0,114,81,0,0,0,114,88,0, + 0,0,41,1,114,96,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,11,95,103,101,116,95,99, + 97,99,104,101,100,171,1,0,0,115,16,0,0,0,0,1, + 14,1,2,1,10,1,14,1,8,1,14,1,4,2,114,112, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,8,0,0,0,67,0,0,0,115,52,0,0, + 0,122,14,116,0,124,0,131,1,106,1,125,1,87,0,110, + 24,4,0,116,2,107,10,114,38,1,0,1,0,1,0,100, + 1,125,1,89,0,110,2,48,0,124,1,100,2,79,0,125, + 1,124,1,83,0,41,3,122,51,67,97,108,99,117,108,97, + 116,101,32,116,104,101,32,109,111,100,101,32,112,101,114,109, + 105,115,115,105,111,110,115,32,102,111,114,32,97,32,98,121, + 116,101,99,111,100,101,32,102,105,108,101,46,114,59,0,0, + 0,233,128,0,0,0,41,3,114,48,0,0,0,114,50,0, + 0,0,114,49,0,0,0,41,2,114,43,0,0,0,114,51, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,10,95,99,97,108,99,95,109,111,100,101,183,1, + 0,0,115,12,0,0,0,0,2,2,1,14,1,14,1,10, + 3,8,1,114,114,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,8,0,0,0,3,0,0, + 0,115,68,0,0,0,100,6,135,0,102,1,100,2,100,3, + 132,9,125,1,122,10,116,0,106,1,125,2,87,0,110,28, + 4,0,116,2,107,10,114,52,1,0,1,0,1,0,100,4, + 100,5,132,0,125,2,89,0,110,2,48,0,124,2,124,1, + 136,0,131,2,1,0,124,1,83,0,41,7,122,252,68,101, + 99,111,114,97,116,111,114,32,116,111,32,118,101,114,105,102, + 121,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, + 101,32,98,101,105,110,103,32,114,101,113,117,101,115,116,101, + 100,32,109,97,116,99,104,101,115,32,116,104,101,32,111,110, + 101,32,116,104,101,10,32,32,32,32,108,111,97,100,101,114, + 32,99,97,110,32,104,97,110,100,108,101,46,10,10,32,32, + 32,32,84,104,101,32,102,105,114,115,116,32,97,114,103,117, + 109,101,110,116,32,40,115,101,108,102,41,32,109,117,115,116, + 32,100,101,102,105,110,101,32,95,110,97,109,101,32,119,104, + 105,99,104,32,116,104,101,32,115,101,99,111,110,100,32,97, + 114,103,117,109,101,110,116,32,105,115,10,32,32,32,32,99, + 111,109,112,97,114,101,100,32,97,103,97,105,110,115,116,46, + 32,73,102,32,116,104,101,32,99,111,109,112,97,114,105,115, + 111,110,32,102,97,105,108,115,32,116,104,101,110,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,46,10,10,32,32,32,32,78,99,2,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, + 31,0,0,0,115,66,0,0,0,124,1,100,0,107,8,114, + 16,124,0,106,0,125,1,110,32,124,0,106,0,124,1,107, + 3,114,48,116,1,100,1,124,0,106,0,124,1,102,2,22, + 0,124,1,100,2,141,2,130,1,136,0,124,0,124,1,102, + 2,124,2,158,2,124,3,142,1,83,0,41,3,78,122,30, + 108,111,97,100,101,114,32,102,111,114,32,37,115,32,99,97, + 110,110,111,116,32,104,97,110,100,108,101,32,37,115,169,1, + 218,4,110,97,109,101,41,2,114,116,0,0,0,218,11,73, + 109,112,111,114,116,69,114,114,111,114,41,4,218,4,115,101, + 108,102,114,116,0,0,0,218,4,97,114,103,115,218,6,107, + 119,97,114,103,115,169,1,218,6,109,101,116,104,111,100,114, + 3,0,0,0,114,6,0,0,0,218,19,95,99,104,101,99, + 107,95,110,97,109,101,95,119,114,97,112,112,101,114,203,1, + 0,0,115,18,0,0,0,0,1,8,1,8,1,10,1,4, + 1,8,255,2,1,2,255,6,2,122,40,95,99,104,101,99, + 107,95,110,97,109,101,46,60,108,111,99,97,108,115,62,46, + 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, + 112,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,7,0,0,0,83,0,0,0,115,56,0,0, + 0,100,1,68,0,93,32,125,2,116,0,124,1,124,2,131, + 2,114,4,116,1,124,0,124,2,116,2,124,1,124,2,131, + 2,131,3,1,0,113,4,124,0,106,3,160,4,124,1,106, + 3,161,1,1,0,100,0,83,0,41,2,78,41,4,218,10, + 95,95,109,111,100,117,108,101,95,95,218,8,95,95,110,97, + 109,101,95,95,218,12,95,95,113,117,97,108,110,97,109,101, + 95,95,218,7,95,95,100,111,99,95,95,41,5,218,7,104, + 97,115,97,116,116,114,218,7,115,101,116,97,116,116,114,218, + 7,103,101,116,97,116,116,114,218,8,95,95,100,105,99,116, + 95,95,218,6,117,112,100,97,116,101,41,3,90,3,110,101, + 119,90,3,111,108,100,114,66,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,5,95,119,114,97, + 112,214,1,0,0,115,8,0,0,0,0,1,8,1,10,1, + 20,1,122,26,95,99,104,101,99,107,95,110,97,109,101,46, + 60,108,111,99,97,108,115,62,46,95,119,114,97,112,41,1, + 78,41,3,218,10,95,98,111,111,116,115,116,114,97,112,114, + 133,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, + 3,114,122,0,0,0,114,123,0,0,0,114,133,0,0,0, + 114,3,0,0,0,114,121,0,0,0,114,6,0,0,0,218, + 11,95,99,104,101,99,107,95,110,97,109,101,195,1,0,0, + 115,14,0,0,0,0,8,14,7,2,1,10,1,14,2,14, + 5,10,1,114,136,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,6,0,0,0,67,0,0, + 0,115,60,0,0,0,124,0,160,0,124,1,161,1,92,2, + 125,2,125,3,124,2,100,1,107,8,114,56,116,1,124,3, + 131,1,114,56,100,2,125,4,116,2,160,3,124,4,160,4, + 124,3,100,3,25,0,161,1,116,5,161,2,1,0,124,2, + 83,0,41,4,122,155,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,32,98,121,32,100,101,108,101,103,97,116,105,110, + 103,32,116,111,10,32,32,32,32,115,101,108,102,46,102,105, + 110,100,95,108,111,97,100,101,114,40,41,46,10,10,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,32,105,110,32,102, + 97,118,111,114,32,111,102,32,102,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,40,41,46,10,10,32,32,32, + 32,78,122,44,78,111,116,32,105,109,112,111,114,116,105,110, + 103,32,100,105,114,101,99,116,111,114,121,32,123,125,58,32, + 109,105,115,115,105,110,103,32,95,95,105,110,105,116,95,95, + 114,72,0,0,0,41,6,218,11,102,105,110,100,95,108,111, + 97,100,101,114,114,22,0,0,0,114,74,0,0,0,114,75, + 0,0,0,114,61,0,0,0,218,13,73,109,112,111,114,116, + 87,97,114,110,105,110,103,41,5,114,118,0,0,0,218,8, + 102,117,108,108,110,97,109,101,218,6,108,111,97,100,101,114, + 218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,17, + 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, + 109,223,1,0,0,115,10,0,0,0,0,10,14,1,16,1, + 4,1,22,1,114,143,0,0,0,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,158,0,0,0,124,0,100,1,100,2,133,2,25, + 0,125,3,124,3,116,0,107,3,114,60,100,3,124,1,155, + 2,100,4,124,3,155,2,157,4,125,4,116,1,160,2,100, + 5,124,4,161,2,1,0,116,3,124,4,102,1,124,2,142, + 1,130,1,116,4,124,0,131,1,100,6,107,0,114,102,100, + 7,124,1,155,2,157,2,125,4,116,1,160,2,100,5,124, + 4,161,2,1,0,116,5,124,4,131,1,130,1,116,6,124, + 0,100,2,100,8,133,2,25,0,131,1,125,5,124,5,100, + 9,64,0,114,154,100,10,124,5,155,2,100,11,124,1,155, + 2,157,4,125,4,116,3,124,4,102,1,124,2,142,1,130, + 1,124,5,83,0,41,12,97,84,2,0,0,80,101,114,102, + 111,114,109,32,98,97,115,105,99,32,118,97,108,105,100,105, + 116,121,32,99,104,101,99,107,105,110,103,32,111,102,32,97, + 32,112,121,99,32,104,101,97,100,101,114,32,97,110,100,32, + 114,101,116,117,114,110,32,116,104,101,32,102,108,97,103,115, + 32,102,105,101,108,100,44,10,32,32,32,32,119,104,105,99, + 104,32,100,101,116,101,114,109,105,110,101,115,32,104,111,119, + 32,116,104,101,32,112,121,99,32,115,104,111,117,108,100,32, + 98,101,32,102,117,114,116,104,101,114,32,118,97,108,105,100, + 97,116,101,100,32,97,103,97,105,110,115,116,32,116,104,101, + 32,115,111,117,114,99,101,46,10,10,32,32,32,32,42,100, 97,116,97,42,32,105,115,32,116,104,101,32,99,111,110,116, 101,110,116,115,32,111,102,32,116,104,101,32,112,121,99,32, 102,105,108,101,46,32,40,79,110,108,121,32,116,104,101,32, 102,105,114,115,116,32,49,54,32,98,121,116,101,115,32,97, - 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,46, - 41,10,10,32,32,32,32,42,115,111,117,114,99,101,95,104, - 97,115,104,42,32,105,115,32,116,104,101,32,105,109,112,111, - 114,116,108,105,98,46,117,116,105,108,46,115,111,117,114,99, - 101,95,104,97,115,104,40,41,32,111,102,32,116,104,101,32, - 115,111,117,114,99,101,32,102,105,108,101,46,10,10,32,32, - 32,32,42,110,97,109,101,42,32,105,115,32,116,104,101,32, - 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, - 108,101,32,98,101,105,110,103,32,105,109,112,111,114,116,101, - 100,46,32,73,116,32,105,115,32,117,115,101,100,32,102,111, - 114,32,108,111,103,103,105,110,103,46,10,10,32,32,32,32, - 42,101,120,99,95,100,101,116,97,105,108,115,42,32,105,115, - 32,97,32,100,105,99,116,105,111,110,97,114,121,32,112,97, - 115,115,101,100,32,116,111,32,73,109,112,111,114,116,69,114, - 114,111,114,32,105,102,32,105,116,32,114,97,105,115,101,100, - 32,102,111,114,10,32,32,32,32,105,109,112,114,111,118,101, - 100,32,100,101,98,117,103,103,105,110,103,46,10,10,32,32, - 32,32,65,110,32,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,116,104, - 101,32,98,121,116,101,99,111,100,101,32,105,115,32,115,116, - 97,108,101,46,10,10,32,32,32,32,114,146,0,0,0,114, - 145,0,0,0,122,46,104,97,115,104,32,105,110,32,98,121, - 116,101,99,111,100,101,32,100,111,101,115,110,39,116,32,109, - 97,116,99,104,32,104,97,115,104,32,111,102,32,115,111,117, - 114,99,101,32,78,41,1,114,117,0,0,0,41,4,114,25, - 0,0,0,218,11,115,111,117,114,99,101,95,104,97,115,104, - 114,116,0,0,0,114,151,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,18,95,118,97,108,105, - 100,97,116,101,95,104,97,115,104,95,112,121,99,43,2,0, - 0,115,12,0,0,0,0,17,16,1,2,1,8,255,2,2, - 2,254,114,158,0,0,0,99,4,0,0,0,0,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,80,0,0,0,116,0,160,1,124,0,161,1,125,4,116, - 2,124,4,116,3,131,2,114,56,116,4,160,5,100,1,124, - 2,161,2,1,0,124,3,100,2,107,9,114,52,116,6,160, - 7,124,4,124,3,161,2,1,0,124,4,83,0,116,8,100, - 3,160,9,124,2,161,1,124,1,124,2,100,4,141,3,130, - 1,100,2,83,0,41,5,122,35,67,111,109,112,105,108,101, - 32,98,121,116,101,99,111,100,101,32,97,115,32,102,111,117, - 110,100,32,105,110,32,97,32,112,121,99,46,122,21,99,111, - 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, - 33,114,125,78,122,23,78,111,110,45,99,111,100,101,32,111, - 98,106,101,99,116,32,105,110,32,123,33,114,125,169,2,114, - 116,0,0,0,114,43,0,0,0,41,10,218,7,109,97,114, - 115,104,97,108,90,5,108,111,97,100,115,218,10,105,115,105, - 110,115,116,97,110,99,101,218,10,95,99,111,100,101,95,116, - 121,112,101,114,134,0,0,0,114,149,0,0,0,218,4,95, - 105,109,112,90,16,95,102,105,120,95,99,111,95,102,105,108, - 101,110,97,109,101,114,117,0,0,0,114,61,0,0,0,41, - 5,114,25,0,0,0,114,116,0,0,0,114,106,0,0,0, - 114,107,0,0,0,218,4,99,111,100,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,17,95,99,111,109, - 112,105,108,101,95,98,121,116,101,99,111,100,101,67,2,0, - 0,115,20,0,0,0,0,2,10,1,10,1,12,1,8,1, - 12,1,4,2,10,1,2,0,2,255,114,165,0,0,0,114, - 72,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,5,0,0,0,67,0,0,0,115,70,0, - 0,0,116,0,116,1,131,1,125,3,124,3,160,2,116,3, - 100,1,131,1,161,1,1,0,124,3,160,2,116,3,124,1, - 131,1,161,1,1,0,124,3,160,2,116,3,124,2,131,1, - 161,1,1,0,124,3,160,2,116,4,160,5,124,0,161,1, - 161,1,1,0,124,3,83,0,41,2,122,43,80,114,111,100, - 117,99,101,32,116,104,101,32,100,97,116,97,32,102,111,114, - 32,97,32,116,105,109,101,115,116,97,109,112,45,98,97,115, - 101,100,32,112,121,99,46,114,72,0,0,0,41,6,218,9, - 98,121,116,101,97,114,114,97,121,114,148,0,0,0,218,6, - 101,120,116,101,110,100,114,20,0,0,0,114,160,0,0,0, - 218,5,100,117,109,112,115,41,4,114,164,0,0,0,218,5, - 109,116,105,109,101,114,155,0,0,0,114,25,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,22, - 95,99,111,100,101,95,116,111,95,116,105,109,101,115,116,97, - 109,112,95,112,121,99,80,2,0,0,115,12,0,0,0,0, - 2,8,1,14,1,14,1,14,1,16,1,114,170,0,0,0, - 84,99,3,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,5,0,0,0,67,0,0,0,115,80,0,0,0,116, - 0,116,1,131,1,125,3,100,1,124,2,100,1,62,0,66, - 0,125,4,124,3,160,2,116,3,124,4,131,1,161,1,1, - 0,116,4,124,1,131,1,100,2,107,2,115,50,74,0,130, - 1,124,3,160,2,124,1,161,1,1,0,124,3,160,2,116, - 5,160,6,124,0,161,1,161,1,1,0,124,3,83,0,41, - 3,122,38,80,114,111,100,117,99,101,32,116,104,101,32,100, - 97,116,97,32,102,111,114,32,97,32,104,97,115,104,45,98, - 97,115,101,100,32,112,121,99,46,114,38,0,0,0,114,146, - 0,0,0,41,7,114,166,0,0,0,114,148,0,0,0,114, - 167,0,0,0,114,20,0,0,0,114,22,0,0,0,114,160, - 0,0,0,114,168,0,0,0,41,5,114,164,0,0,0,114, - 157,0,0,0,90,7,99,104,101,99,107,101,100,114,25,0, - 0,0,114,82,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,17,95,99,111,100,101,95,116,111, - 95,104,97,115,104,95,112,121,99,90,2,0,0,115,14,0, - 0,0,0,2,8,1,12,1,14,1,16,1,10,1,16,1, - 114,171,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,6,0,0,0,67,0,0,0,115,62, - 0,0,0,100,1,100,2,108,0,125,1,116,1,160,2,124, - 0,161,1,106,3,125,2,124,1,160,4,124,2,161,1,125, - 3,116,1,160,5,100,2,100,3,161,2,125,4,124,4,160, - 6,124,0,160,6,124,3,100,1,25,0,161,1,161,1,83, - 0,41,4,122,121,68,101,99,111,100,101,32,98,121,116,101, - 115,32,114,101,112,114,101,115,101,110,116,105,110,103,32,115, - 111,117,114,99,101,32,99,111,100,101,32,97,110,100,32,114, - 101,116,117,114,110,32,116,104,101,32,115,116,114,105,110,103, - 46,10,10,32,32,32,32,85,110,105,118,101,114,115,97,108, - 32,110,101,119,108,105,110,101,32,115,117,112,112,111,114,116, - 32,105,115,32,117,115,101,100,32,105,110,32,116,104,101,32, - 100,101,99,111,100,105,110,103,46,10,32,32,32,32,114,72, - 0,0,0,78,84,41,7,218,8,116,111,107,101,110,105,122, - 101,114,63,0,0,0,90,7,66,121,116,101,115,73,79,90, - 8,114,101,97,100,108,105,110,101,90,15,100,101,116,101,99, - 116,95,101,110,99,111,100,105,110,103,90,25,73,110,99,114, - 101,109,101,110,116,97,108,78,101,119,108,105,110,101,68,101, - 99,111,100,101,114,218,6,100,101,99,111,100,101,41,5,218, - 12,115,111,117,114,99,101,95,98,121,116,101,115,114,172,0, - 0,0,90,21,115,111,117,114,99,101,95,98,121,116,101,115, - 95,114,101,97,100,108,105,110,101,218,8,101,110,99,111,100, - 105,110,103,90,15,110,101,119,108,105,110,101,95,100,101,99, - 111,100,101,114,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,13,100,101,99,111,100,101,95,115,111,117,114, - 99,101,101,2,0,0,115,10,0,0,0,0,5,8,1,12, - 1,10,1,12,1,114,176,0,0,0,169,2,114,140,0,0, - 0,218,26,115,117,98,109,111,100,117,108,101,95,115,101,97, - 114,99,104,95,108,111,99,97,116,105,111,110,115,99,2,0, - 0,0,0,0,0,0,2,0,0,0,9,0,0,0,8,0, - 0,0,67,0,0,0,115,16,1,0,0,124,1,100,1,107, - 8,114,60,100,2,125,1,116,0,124,2,100,3,131,2,114, - 70,122,14,124,2,160,1,124,0,161,1,125,1,87,0,113, - 70,4,0,116,2,107,10,114,56,1,0,1,0,1,0,89, - 0,113,70,88,0,110,10,116,3,160,4,124,1,161,1,125, - 1,116,5,106,6,124,0,124,2,124,1,100,4,141,3,125, - 4,100,5,124,4,95,7,124,2,100,1,107,8,114,154,116, - 8,131,0,68,0,93,42,92,2,125,5,125,6,124,1,160, - 9,116,10,124,6,131,1,161,1,114,106,124,5,124,0,124, - 1,131,2,125,2,124,2,124,4,95,11,1,0,113,154,113, - 106,100,1,83,0,124,3,116,12,107,8,114,220,116,0,124, - 2,100,6,131,2,114,226,122,14,124,2,160,13,124,0,161, - 1,125,7,87,0,110,20,4,0,116,2,107,10,114,206,1, - 0,1,0,1,0,89,0,113,226,88,0,124,7,114,226,103, - 0,124,4,95,14,110,6,124,3,124,4,95,14,124,4,106, - 14,103,0,107,2,144,1,114,12,124,1,144,1,114,12,116, - 15,124,1,131,1,100,7,25,0,125,8,124,4,106,14,160, - 16,124,8,161,1,1,0,124,4,83,0,41,8,97,61,1, - 0,0,82,101,116,117,114,110,32,97,32,109,111,100,117,108, - 101,32,115,112,101,99,32,98,97,115,101,100,32,111,110,32, - 97,32,102,105,108,101,32,108,111,99,97,116,105,111,110,46, - 10,10,32,32,32,32,84,111,32,105,110,100,105,99,97,116, - 101,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,44,32, - 115,101,116,10,32,32,32,32,115,117,98,109,111,100,117,108, - 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, - 110,115,32,116,111,32,97,32,108,105,115,116,32,111,102,32, - 100,105,114,101,99,116,111,114,121,32,112,97,116,104,115,46, - 32,32,65,110,10,32,32,32,32,101,109,112,116,121,32,108, - 105,115,116,32,105,115,32,115,117,102,102,105,99,105,101,110, - 116,44,32,116,104,111,117,103,104,32,105,116,115,32,110,111, - 116,32,111,116,104,101,114,119,105,115,101,32,117,115,101,102, - 117,108,32,116,111,32,116,104,101,10,32,32,32,32,105,109, - 112,111,114,116,32,115,121,115,116,101,109,46,10,10,32,32, - 32,32,84,104,101,32,108,111,97,100,101,114,32,109,117,115, - 116,32,116,97,107,101,32,97,32,115,112,101,99,32,97,115, - 32,105,116,115,32,111,110,108,121,32,95,95,105,110,105,116, - 95,95,40,41,32,97,114,103,46,10,10,32,32,32,32,78, - 122,9,60,117,110,107,110,111,119,110,62,218,12,103,101,116, - 95,102,105,108,101,110,97,109,101,169,1,218,6,111,114,105, - 103,105,110,84,218,10,105,115,95,112,97,99,107,97,103,101, - 114,72,0,0,0,41,17,114,128,0,0,0,114,179,0,0, - 0,114,117,0,0,0,114,2,0,0,0,114,78,0,0,0, - 114,134,0,0,0,218,10,77,111,100,117,108,101,83,112,101, - 99,90,13,95,115,101,116,95,102,105,108,101,97,116,116,114, - 218,27,95,103,101,116,95,115,117,112,112,111,114,116,101,100, - 95,102,105,108,101,95,108,111,97,100,101,114,115,114,110,0, - 0,0,114,111,0,0,0,114,140,0,0,0,218,9,95,80, - 79,80,85,76,65,84,69,114,182,0,0,0,114,178,0,0, - 0,114,46,0,0,0,218,6,97,112,112,101,110,100,41,9, - 114,116,0,0,0,90,8,108,111,99,97,116,105,111,110,114, - 140,0,0,0,114,178,0,0,0,218,4,115,112,101,99,218, - 12,108,111,97,100,101,114,95,99,108,97,115,115,218,8,115, - 117,102,102,105,120,101,115,114,182,0,0,0,90,7,100,105, - 114,110,97,109,101,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,23,115,112,101,99,95,102,114,111,109,95, - 102,105,108,101,95,108,111,99,97,116,105,111,110,118,2,0, - 0,115,62,0,0,0,0,12,8,4,4,1,10,2,2,1, - 14,1,14,1,8,2,10,8,16,1,6,3,8,1,14,1, - 14,1,10,1,6,1,6,2,4,3,8,2,10,1,2,1, - 14,1,14,1,6,2,4,1,8,2,6,1,12,1,6,1, - 12,1,12,2,114,190,0,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,80,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,90,4,100,3,90,5,100,4,90,6,101, - 7,100,5,100,6,132,0,131,1,90,8,101,7,100,7,100, - 8,132,0,131,1,90,9,101,7,100,14,100,10,100,11,132, - 1,131,1,90,10,101,7,100,15,100,12,100,13,132,1,131, - 1,90,11,100,9,83,0,41,16,218,21,87,105,110,100,111, - 119,115,82,101,103,105,115,116,114,121,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,109,111,100,117,108,101,115,32,100, - 101,99,108,97,114,101,100,32,105,110,32,116,104,101,32,87, - 105,110,100,111,119,115,32,114,101,103,105,115,116,114,121,46, - 122,59,83,111,102,116,119,97,114,101,92,80,121,116,104,111, - 110,92,80,121,116,104,111,110,67,111,114,101,92,123,115,121, - 115,95,118,101,114,115,105,111,110,125,92,77,111,100,117,108, - 101,115,92,123,102,117,108,108,110,97,109,101,125,122,65,83, - 111,102,116,119,97,114,101,92,80,121,116,104,111,110,92,80, - 121,116,104,111,110,67,111,114,101,92,123,115,121,115,95,118, - 101,114,115,105,111,110,125,92,77,111,100,117,108,101,115,92, - 123,102,117,108,108,110,97,109,101,125,92,68,101,98,117,103, - 70,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,8,0,0,0,67,0,0,0,115,56,0,0,0,122, - 16,116,0,160,1,116,0,106,2,124,1,161,2,87,0,83, - 0,4,0,116,3,107,10,114,50,1,0,1,0,1,0,116, - 0,160,1,116,0,106,4,124,1,161,2,6,0,89,0,83, - 0,88,0,100,0,83,0,114,109,0,0,0,41,5,218,7, - 95,119,105,110,114,101,103,90,7,79,112,101,110,75,101,121, - 90,17,72,75,69,89,95,67,85,82,82,69,78,84,95,85, - 83,69,82,114,49,0,0,0,90,18,72,75,69,89,95,76, - 79,67,65,76,95,77,65,67,72,73,78,69,41,2,218,3, - 99,108,115,114,5,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,14,95,111,112,101,110,95,114, - 101,103,105,115,116,114,121,198,2,0,0,115,8,0,0,0, - 0,2,2,1,16,1,14,1,122,36,87,105,110,100,111,119, - 115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46, - 95,111,112,101,110,95,114,101,103,105,115,116,114,121,99,2, - 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,9, - 0,0,0,67,0,0,0,115,114,0,0,0,124,0,106,0, - 114,14,124,0,106,1,125,2,110,6,124,0,106,2,125,2, - 124,2,106,3,124,1,100,1,116,4,106,5,100,0,100,2, - 133,2,25,0,22,0,100,3,141,2,125,3,122,38,124,0, - 160,6,124,3,161,1,143,18,125,4,116,7,160,8,124,4, - 100,4,161,2,125,5,87,0,53,0,81,0,82,0,88,0, - 87,0,110,22,4,0,116,9,107,10,114,108,1,0,1,0, - 1,0,89,0,100,0,83,0,88,0,124,5,83,0,41,5, - 78,122,5,37,100,46,37,100,114,27,0,0,0,41,2,114, - 139,0,0,0,90,11,115,121,115,95,118,101,114,115,105,111, - 110,114,39,0,0,0,41,10,218,11,68,69,66,85,71,95, - 66,85,73,76,68,218,18,82,69,71,73,83,84,82,89,95, - 75,69,89,95,68,69,66,85,71,218,12,82,69,71,73,83, - 84,82,89,95,75,69,89,114,61,0,0,0,114,8,0,0, - 0,218,12,118,101,114,115,105,111,110,95,105,110,102,111,114, - 194,0,0,0,114,192,0,0,0,90,10,81,117,101,114,121, - 86,97,108,117,101,114,49,0,0,0,41,6,114,193,0,0, - 0,114,139,0,0,0,90,12,114,101,103,105,115,116,114,121, - 95,107,101,121,114,5,0,0,0,90,4,104,107,101,121,218, - 8,102,105,108,101,112,97,116,104,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,16,95,115,101,97,114,99, - 104,95,114,101,103,105,115,116,114,121,205,2,0,0,115,24, - 0,0,0,0,2,6,1,8,2,6,1,6,1,16,255,6, - 2,2,1,12,1,26,1,14,1,8,1,122,38,87,105,110, - 100,111,119,115,82,101,103,105,115,116,114,121,70,105,110,100, - 101,114,46,95,115,101,97,114,99,104,95,114,101,103,105,115, - 116,114,121,78,99,4,0,0,0,0,0,0,0,0,0,0, - 0,8,0,0,0,8,0,0,0,67,0,0,0,115,122,0, - 0,0,124,0,160,0,124,1,161,1,125,4,124,4,100,0, - 107,8,114,22,100,0,83,0,122,12,116,1,124,4,131,1, - 1,0,87,0,110,22,4,0,116,2,107,10,114,56,1,0, - 1,0,1,0,89,0,100,0,83,0,88,0,116,3,131,0, - 68,0,93,52,92,2,125,5,125,6,124,4,160,4,116,5, - 124,6,131,1,161,1,114,64,116,6,106,7,124,1,124,5, - 124,1,124,4,131,2,124,4,100,1,141,3,125,7,124,7, - 2,0,1,0,83,0,113,64,100,0,83,0,41,2,78,114, - 180,0,0,0,41,8,114,200,0,0,0,114,48,0,0,0, - 114,49,0,0,0,114,184,0,0,0,114,110,0,0,0,114, - 111,0,0,0,114,134,0,0,0,218,16,115,112,101,99,95, - 102,114,111,109,95,108,111,97,100,101,114,41,8,114,193,0, - 0,0,114,139,0,0,0,114,43,0,0,0,218,6,116,97, - 114,103,101,116,114,199,0,0,0,114,140,0,0,0,114,189, - 0,0,0,114,187,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,9,102,105,110,100,95,115,112, - 101,99,220,2,0,0,115,28,0,0,0,0,2,10,1,8, - 1,4,1,2,1,12,1,14,1,8,1,14,1,14,1,6, - 1,8,1,2,254,6,3,122,31,87,105,110,100,111,119,115, - 82,101,103,105,115,116,114,121,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,34,0,0,0,124,0,160,0,124,1,124,2,161,2, - 125,3,124,3,100,1,107,9,114,26,124,3,106,1,83,0, - 100,1,83,0,100,1,83,0,41,2,122,108,70,105,110,100, - 32,109,111,100,117,108,101,32,110,97,109,101,100,32,105,110, - 32,116,104,101,32,114,101,103,105,115,116,114,121,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,78,169,2,114,203,0,0,0, - 114,140,0,0,0,169,4,114,193,0,0,0,114,139,0,0, - 0,114,43,0,0,0,114,187,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,11,102,105,110,100, - 95,109,111,100,117,108,101,236,2,0,0,115,8,0,0,0, - 0,7,12,1,8,1,6,2,122,33,87,105,110,100,111,119, - 115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46, - 102,105,110,100,95,109,111,100,117,108,101,41,2,78,78,41, - 1,78,41,12,114,125,0,0,0,114,124,0,0,0,114,126, - 0,0,0,114,127,0,0,0,114,197,0,0,0,114,196,0, - 0,0,114,195,0,0,0,218,11,99,108,97,115,115,109,101, - 116,104,111,100,114,194,0,0,0,114,200,0,0,0,114,203, - 0,0,0,114,206,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,191,0,0, - 0,186,2,0,0,115,28,0,0,0,8,2,4,3,2,255, - 2,4,2,255,2,3,4,2,2,1,10,6,2,1,10,14, - 2,1,12,15,2,1,114,191,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,48,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,83,0,41,11,218,13,95,76,111, - 97,100,101,114,66,97,115,105,99,115,122,83,66,97,115,101, - 32,99,108,97,115,115,32,111,102,32,99,111,109,109,111,110, - 32,99,111,100,101,32,110,101,101,100,101,100,32,98,121,32, - 98,111,116,104,32,83,111,117,114,99,101,76,111,97,100,101, - 114,32,97,110,100,10,32,32,32,32,83,111,117,114,99,101, - 108,101,115,115,70,105,108,101,76,111,97,100,101,114,46,99, - 2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 4,0,0,0,67,0,0,0,115,64,0,0,0,116,0,124, - 0,160,1,124,1,161,1,131,1,100,1,25,0,125,2,124, - 2,160,2,100,2,100,1,161,2,100,3,25,0,125,3,124, - 1,160,3,100,2,161,1,100,4,25,0,125,4,124,3,100, - 5,107,2,111,62,124,4,100,5,107,3,83,0,41,6,122, - 141,67,111,110,99,114,101,116,101,32,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,32,111,102,32,73,110,115,112, - 101,99,116,76,111,97,100,101,114,46,105,115,95,112,97,99, - 107,97,103,101,32,98,121,32,99,104,101,99,107,105,110,103, - 32,105,102,10,32,32,32,32,32,32,32,32,116,104,101,32, - 112,97,116,104,32,114,101,116,117,114,110,101,100,32,98,121, - 32,103,101,116,95,102,105,108,101,110,97,109,101,32,104,97, - 115,32,97,32,102,105,108,101,110,97,109,101,32,111,102,32, - 39,95,95,105,110,105,116,95,95,46,112,121,39,46,114,38, - 0,0,0,114,70,0,0,0,114,72,0,0,0,114,27,0, - 0,0,218,8,95,95,105,110,105,116,95,95,41,4,114,46, - 0,0,0,114,179,0,0,0,114,42,0,0,0,114,40,0, - 0,0,41,5,114,118,0,0,0,114,139,0,0,0,114,96, - 0,0,0,90,13,102,105,108,101,110,97,109,101,95,98,97, - 115,101,90,9,116,97,105,108,95,110,97,109,101,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,182,0,0, - 0,255,2,0,0,115,8,0,0,0,0,3,18,1,16,1, - 14,1,122,24,95,76,111,97,100,101,114,66,97,115,105,99, - 115,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,169,2, - 122,42,85,115,101,32,100,101,102,97,117,108,116,32,115,101, - 109,97,110,116,105,99,115,32,102,111,114,32,109,111,100,117, - 108,101,32,99,114,101,97,116,105,111,110,46,78,114,3,0, - 0,0,169,2,114,118,0,0,0,114,187,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,13,99, - 114,101,97,116,101,95,109,111,100,117,108,101,7,3,0,0, - 115,2,0,0,0,0,1,122,27,95,76,111,97,100,101,114, - 66,97,115,105,99,115,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,3,0,0,0,5,0,0,0,67,0,0,0,115,56,0, - 0,0,124,0,160,0,124,1,106,1,161,1,125,2,124,2, - 100,1,107,8,114,36,116,2,100,2,160,3,124,1,106,1, - 161,1,131,1,130,1,116,4,160,5,116,6,124,2,124,1, - 106,7,161,3,1,0,100,1,83,0,41,3,122,19,69,120, - 101,99,117,116,101,32,116,104,101,32,109,111,100,117,108,101, - 46,78,122,52,99,97,110,110,111,116,32,108,111,97,100,32, - 109,111,100,117,108,101,32,123,33,114,125,32,119,104,101,110, - 32,103,101,116,95,99,111,100,101,40,41,32,114,101,116,117, - 114,110,115,32,78,111,110,101,41,8,218,8,103,101,116,95, - 99,111,100,101,114,125,0,0,0,114,117,0,0,0,114,61, - 0,0,0,114,134,0,0,0,218,25,95,99,97,108,108,95, - 119,105,116,104,95,102,114,97,109,101,115,95,114,101,109,111, - 118,101,100,218,4,101,120,101,99,114,131,0,0,0,41,3, - 114,118,0,0,0,218,6,109,111,100,117,108,101,114,164,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,11,101,120,101,99,95,109,111,100,117,108,101,10,3, - 0,0,115,12,0,0,0,0,2,12,1,8,1,6,1,4, - 255,6,2,122,25,95,76,111,97,100,101,114,66,97,115,105, - 99,115,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,12,0,0,0,116,0,160,1, - 124,0,124,1,161,2,83,0,41,1,122,26,84,104,105,115, - 32,109,111,100,117,108,101,32,105,115,32,100,101,112,114,101, - 99,97,116,101,100,46,41,2,114,134,0,0,0,218,17,95, - 108,111,97,100,95,109,111,100,117,108,101,95,115,104,105,109, - 169,2,114,118,0,0,0,114,139,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,11,108,111,97, - 100,95,109,111,100,117,108,101,18,3,0,0,115,2,0,0, - 0,0,2,122,25,95,76,111,97,100,101,114,66,97,115,105, - 99,115,46,108,111,97,100,95,109,111,100,117,108,101,78,41, - 8,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,182,0,0,0,114,212,0,0,0,114, - 217,0,0,0,114,220,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,208,0, - 0,0,250,2,0,0,115,10,0,0,0,8,2,4,3,8, - 8,8,3,8,8,114,208,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,74,0,0,0,101,0,90,1,100,0,90,2, - 100,1,100,2,132,0,90,3,100,3,100,4,132,0,90,4, - 100,5,100,6,132,0,90,5,100,7,100,8,132,0,90,6, - 100,9,100,10,132,0,90,7,100,11,100,12,156,1,100,13, - 100,14,132,2,90,8,100,15,100,16,132,0,90,9,100,17, - 83,0,41,18,218,12,83,111,117,114,99,101,76,111,97,100, - 101,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,8,0,0,0, - 116,0,130,1,100,1,83,0,41,2,122,165,79,112,116,105, - 111,110,97,108,32,109,101,116,104,111,100,32,116,104,97,116, - 32,114,101,116,117,114,110,115,32,116,104,101,32,109,111,100, - 105,102,105,99,97,116,105,111,110,32,116,105,109,101,32,40, - 97,110,32,105,110,116,41,32,102,111,114,32,116,104,101,10, - 32,32,32,32,32,32,32,32,115,112,101,99,105,102,105,101, - 100,32,112,97,116,104,32,40,97,32,115,116,114,41,46,10, - 10,32,32,32,32,32,32,32,32,82,97,105,115,101,115,32, - 79,83,69,114,114,111,114,32,119,104,101,110,32,116,104,101, - 32,112,97,116,104,32,99,97,110,110,111,116,32,98,101,32, - 104,97,110,100,108,101,100,46,10,32,32,32,32,32,32,32, - 32,78,41,1,114,49,0,0,0,169,2,114,118,0,0,0, - 114,43,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,10,112,97,116,104,95,109,116,105,109,101, - 25,3,0,0,115,2,0,0,0,0,6,122,23,83,111,117, - 114,99,101,76,111,97,100,101,114,46,112,97,116,104,95,109, - 116,105,109,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,14,0, - 0,0,100,1,124,0,160,0,124,1,161,1,105,1,83,0, - 41,2,97,158,1,0,0,79,112,116,105,111,110,97,108,32, - 109,101,116,104,111,100,32,114,101,116,117,114,110,105,110,103, - 32,97,32,109,101,116,97,100,97,116,97,32,100,105,99,116, - 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, - 101,100,10,32,32,32,32,32,32,32,32,112,97,116,104,32, - 40,97,32,115,116,114,41,46,10,10,32,32,32,32,32,32, - 32,32,80,111,115,115,105,98,108,101,32,107,101,121,115,58, - 10,32,32,32,32,32,32,32,32,45,32,39,109,116,105,109, - 101,39,32,40,109,97,110,100,97,116,111,114,121,41,32,105, - 115,32,116,104,101,32,110,117,109,101,114,105,99,32,116,105, - 109,101,115,116,97,109,112,32,111,102,32,108,97,115,116,32, - 115,111,117,114,99,101,10,32,32,32,32,32,32,32,32,32, - 32,99,111,100,101,32,109,111,100,105,102,105,99,97,116,105, - 111,110,59,10,32,32,32,32,32,32,32,32,45,32,39,115, - 105,122,101,39,32,40,111,112,116,105,111,110,97,108,41,32, - 105,115,32,116,104,101,32,115,105,122,101,32,105,110,32,98, - 121,116,101,115,32,111,102,32,116,104,101,32,115,111,117,114, - 99,101,32,99,111,100,101,46,10,10,32,32,32,32,32,32, - 32,32,73,109,112,108,101,109,101,110,116,105,110,103,32,116, - 104,105,115,32,109,101,116,104,111,100,32,97,108,108,111,119, - 115,32,116,104,101,32,108,111,97,100,101,114,32,116,111,32, - 114,101,97,100,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,115,46,10,32,32,32,32,32,32,32,32,82,97,105, - 115,101,115,32,79,83,69,114,114,111,114,32,119,104,101,110, - 32,116,104,101,32,112,97,116,104,32,99,97,110,110,111,116, - 32,98,101,32,104,97,110,100,108,101,100,46,10,32,32,32, - 32,32,32,32,32,114,169,0,0,0,41,1,114,223,0,0, - 0,114,222,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,10,112,97,116,104,95,115,116,97,116, - 115,33,3,0,0,115,2,0,0,0,0,12,122,23,83,111, - 117,114,99,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,0, - 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,12, - 0,0,0,124,0,160,0,124,2,124,3,161,2,83,0,41, - 1,122,228,79,112,116,105,111,110,97,108,32,109,101,116,104, - 111,100,32,119,104,105,99,104,32,119,114,105,116,101,115,32, - 100,97,116,97,32,40,98,121,116,101,115,41,32,116,111,32, - 97,32,102,105,108,101,32,112,97,116,104,32,40,97,32,115, - 116,114,41,46,10,10,32,32,32,32,32,32,32,32,73,109, - 112,108,101,109,101,110,116,105,110,103,32,116,104,105,115,32, - 109,101,116,104,111,100,32,97,108,108,111,119,115,32,102,111, - 114,32,116,104,101,32,119,114,105,116,105,110,103,32,111,102, - 32,98,121,116,101,99,111,100,101,32,102,105,108,101,115,46, - 10,10,32,32,32,32,32,32,32,32,84,104,101,32,115,111, - 117,114,99,101,32,112,97,116,104,32,105,115,32,110,101,101, - 100,101,100,32,105,110,32,111,114,100,101,114,32,116,111,32, - 99,111,114,114,101,99,116,108,121,32,116,114,97,110,115,102, - 101,114,32,112,101,114,109,105,115,115,105,111,110,115,10,32, - 32,32,32,32,32,32,32,41,1,218,8,115,101,116,95,100, - 97,116,97,41,4,114,118,0,0,0,114,107,0,0,0,90, - 10,99,97,99,104,101,95,112,97,116,104,114,25,0,0,0, + 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,44, + 32,116,104,111,117,103,104,46,41,10,10,32,32,32,32,42, + 110,97,109,101,42,32,105,115,32,116,104,101,32,110,97,109, + 101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,32, + 98,101,105,110,103,32,105,109,112,111,114,116,101,100,46,32, + 73,116,32,105,115,32,117,115,101,100,32,102,111,114,32,108, + 111,103,103,105,110,103,46,10,10,32,32,32,32,42,101,120, + 99,95,100,101,116,97,105,108,115,42,32,105,115,32,97,32, + 100,105,99,116,105,111,110,97,114,121,32,112,97,115,115,101, + 100,32,116,111,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,102,32,105,116,32,114,97,105,115,101,100,32,102,111, + 114,10,32,32,32,32,105,109,112,114,111,118,101,100,32,100, + 101,98,117,103,103,105,110,103,46,10,10,32,32,32,32,73, + 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97, + 105,115,101,100,32,119,104,101,110,32,116,104,101,32,109,97, + 103,105,99,32,110,117,109,98,101,114,32,105,115,32,105,110, + 99,111,114,114,101,99,116,32,111,114,32,119,104,101,110,32, + 116,104,101,32,102,108,97,103,115,10,32,32,32,32,102,105, + 101,108,100,32,105,115,32,105,110,118,97,108,105,100,46,32, + 69,79,70,69,114,114,111,114,32,105,115,32,114,97,105,115, + 101,100,32,119,104,101,110,32,116,104,101,32,100,97,116,97, + 32,105,115,32,102,111,117,110,100,32,116,111,32,98,101,32, + 116,114,117,110,99,97,116,101,100,46,10,10,32,32,32,32, + 78,114,15,0,0,0,122,20,98,97,100,32,109,97,103,105, + 99,32,110,117,109,98,101,114,32,105,110,32,122,2,58,32, + 250,2,123,125,233,16,0,0,0,122,40,114,101,97,99,104, + 101,100,32,69,79,70,32,119,104,105,108,101,32,114,101,97, + 100,105,110,103,32,112,121,99,32,104,101,97,100,101,114,32, + 111,102,32,233,8,0,0,0,233,252,255,255,255,122,14,105, + 110,118,97,108,105,100,32,102,108,97,103,115,32,122,4,32, + 105,110,32,41,7,218,12,77,65,71,73,67,95,78,85,77, + 66,69,82,114,134,0,0,0,218,16,95,118,101,114,98,111, + 115,101,95,109,101,115,115,97,103,101,114,117,0,0,0,114, + 22,0,0,0,218,8,69,79,70,69,114,114,111,114,114,26, + 0,0,0,41,6,114,25,0,0,0,114,116,0,0,0,218, + 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, + 103,105,99,114,92,0,0,0,114,82,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,240,1,0,0,115, + 28,0,0,0,0,16,12,1,8,1,16,1,12,1,12,1, + 12,1,10,1,12,1,8,1,16,2,8,1,16,1,12,1, + 114,152,0,0,0,99,5,0,0,0,0,0,0,0,0,0, + 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,112, + 0,0,0,116,0,124,0,100,1,100,2,133,2,25,0,131, + 1,124,1,100,3,64,0,107,3,114,58,100,4,124,3,155, + 2,157,2,125,5,116,1,160,2,100,5,124,5,161,2,1, + 0,116,3,124,5,102,1,124,4,142,1,130,1,124,2,100, + 6,107,9,114,108,116,0,124,0,100,2,100,7,133,2,25, + 0,131,1,124,2,100,3,64,0,107,3,114,108,116,3,100, + 4,124,3,155,2,157,2,102,1,124,4,142,1,130,1,100, + 6,83,0,41,8,97,7,2,0,0,86,97,108,105,100,97, + 116,101,32,97,32,112,121,99,32,97,103,97,105,110,115,116, + 32,116,104,101,32,115,111,117,114,99,101,32,108,97,115,116, + 45,109,111,100,105,102,105,101,100,32,116,105,109,101,46,10, + 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, + 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, + 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, + 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, + 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, + 113,117,105,114,101,100,46,41,10,10,32,32,32,32,42,115, + 111,117,114,99,101,95,109,116,105,109,101,42,32,105,115,32, + 116,104,101,32,108,97,115,116,32,109,111,100,105,102,105,101, + 100,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116, + 104,101,32,115,111,117,114,99,101,32,102,105,108,101,46,10, + 10,32,32,32,32,42,115,111,117,114,99,101,95,115,105,122, + 101,42,32,105,115,32,78,111,110,101,32,111,114,32,116,104, + 101,32,115,105,122,101,32,111,102,32,116,104,101,32,115,111, + 117,114,99,101,32,102,105,108,101,32,105,110,32,98,121,116, + 101,115,46,10,10,32,32,32,32,42,110,97,109,101,42,32, + 105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,116, + 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, + 105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,32, + 117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,103, + 46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,97, + 105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,111, + 110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,73, + 109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,116, + 32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,32, + 105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,105, + 110,103,46,10,10,32,32,32,32,65,110,32,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,116,104,101,32,98,121,116,101,99,111,100, + 101,32,105,115,32,115,116,97,108,101,46,10,10,32,32,32, + 32,114,146,0,0,0,233,12,0,0,0,114,14,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,114,144,0,0,0,78,114,145, + 0,0,0,41,4,114,26,0,0,0,114,134,0,0,0,114, + 149,0,0,0,114,117,0,0,0,41,6,114,25,0,0,0, + 218,12,115,111,117,114,99,101,95,109,116,105,109,101,218,11, + 115,111,117,114,99,101,95,115,105,122,101,114,116,0,0,0, + 114,151,0,0,0,114,92,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,23,95,118,97,108,105, + 100,97,116,101,95,116,105,109,101,115,116,97,109,112,95,112, + 121,99,17,2,0,0,115,16,0,0,0,0,19,24,1,10, + 1,12,1,12,1,8,1,22,255,2,2,114,156,0,0,0, + 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,38,0,0,0,124,0, + 100,1,100,2,133,2,25,0,124,1,107,3,114,34,116,0, + 100,3,124,2,155,2,157,2,102,1,124,3,142,1,130,1, + 100,4,83,0,41,5,97,243,1,0,0,86,97,108,105,100, + 97,116,101,32,97,32,104,97,115,104,45,98,97,115,101,100, + 32,112,121,99,32,98,121,32,99,104,101,99,107,105,110,103, + 32,116,104,101,32,114,101,97,108,32,115,111,117,114,99,101, + 32,104,97,115,104,32,97,103,97,105,110,115,116,32,116,104, + 101,32,111,110,101,32,105,110,10,32,32,32,32,116,104,101, + 32,112,121,99,32,104,101,97,100,101,114,46,10,10,32,32, + 32,32,42,100,97,116,97,42,32,105,115,32,116,104,101,32, + 99,111,110,116,101,110,116,115,32,111,102,32,116,104,101,32, + 112,121,99,32,102,105,108,101,46,32,40,79,110,108,121,32, + 116,104,101,32,102,105,114,115,116,32,49,54,32,98,121,116, + 101,115,32,97,114,101,10,32,32,32,32,114,101,113,117,105, + 114,101,100,46,41,10,10,32,32,32,32,42,115,111,117,114, + 99,101,95,104,97,115,104,42,32,105,115,32,116,104,101,32, + 105,109,112,111,114,116,108,105,98,46,117,116,105,108,46,115, + 111,117,114,99,101,95,104,97,115,104,40,41,32,111,102,32, + 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,46, + 10,10,32,32,32,32,42,110,97,109,101,42,32,105,115,32, + 116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,32, + 109,111,100,117,108,101,32,98,101,105,110,103,32,105,109,112, + 111,114,116,101,100,46,32,73,116,32,105,115,32,117,115,101, + 100,32,102,111,114,32,108,111,103,103,105,110,103,46,10,10, + 32,32,32,32,42,101,120,99,95,100,101,116,97,105,108,115, + 42,32,105,115,32,97,32,100,105,99,116,105,111,110,97,114, + 121,32,112,97,115,115,101,100,32,116,111,32,73,109,112,111, + 114,116,69,114,114,111,114,32,105,102,32,105,116,32,114,97, + 105,115,101,100,32,102,111,114,10,32,32,32,32,105,109,112, + 114,111,118,101,100,32,100,101,98,117,103,103,105,110,103,46, + 10,10,32,32,32,32,65,110,32,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,116,104,101,32,98,121,116,101,99,111,100,101,32,105, + 115,32,115,116,97,108,101,46,10,10,32,32,32,32,114,146, + 0,0,0,114,145,0,0,0,122,46,104,97,115,104,32,105, + 110,32,98,121,116,101,99,111,100,101,32,100,111,101,115,110, + 39,116,32,109,97,116,99,104,32,104,97,115,104,32,111,102, + 32,115,111,117,114,99,101,32,78,41,1,114,117,0,0,0, + 41,4,114,25,0,0,0,218,11,115,111,117,114,99,101,95, + 104,97,115,104,114,116,0,0,0,114,151,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,18,95, + 118,97,108,105,100,97,116,101,95,104,97,115,104,95,112,121, + 99,45,2,0,0,115,12,0,0,0,0,17,16,1,2,1, + 8,255,2,2,2,254,114,158,0,0,0,99,4,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,80,0,0,0,116,0,160,1,124,0,161, + 1,125,4,116,2,124,4,116,3,131,2,114,56,116,4,160, + 5,100,1,124,2,161,2,1,0,124,3,100,2,107,9,114, + 52,116,6,160,7,124,4,124,3,161,2,1,0,124,4,83, + 0,116,8,100,3,160,9,124,2,161,1,124,1,124,2,100, + 4,141,3,130,1,100,2,83,0,41,5,122,35,67,111,109, + 112,105,108,101,32,98,121,116,101,99,111,100,101,32,97,115, + 32,102,111,117,110,100,32,105,110,32,97,32,112,121,99,46, + 122,21,99,111,100,101,32,111,98,106,101,99,116,32,102,114, + 111,109,32,123,33,114,125,78,122,23,78,111,110,45,99,111, + 100,101,32,111,98,106,101,99,116,32,105,110,32,123,33,114, + 125,169,2,114,116,0,0,0,114,43,0,0,0,41,10,218, + 7,109,97,114,115,104,97,108,90,5,108,111,97,100,115,218, + 10,105,115,105,110,115,116,97,110,99,101,218,10,95,99,111, + 100,101,95,116,121,112,101,114,134,0,0,0,114,149,0,0, + 0,218,4,95,105,109,112,90,16,95,102,105,120,95,99,111, + 95,102,105,108,101,110,97,109,101,114,117,0,0,0,114,61, + 0,0,0,41,5,114,25,0,0,0,114,116,0,0,0,114, + 106,0,0,0,114,107,0,0,0,218,4,99,111,100,101,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,17, + 95,99,111,109,112,105,108,101,95,98,121,116,101,99,111,100, + 101,69,2,0,0,115,20,0,0,0,0,2,10,1,10,1, + 12,1,8,1,12,1,4,2,10,1,2,0,2,255,114,165, + 0,0,0,114,72,0,0,0,99,3,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, + 0,115,70,0,0,0,116,0,116,1,131,1,125,3,124,3, + 160,2,116,3,100,1,131,1,161,1,1,0,124,3,160,2, + 116,3,124,1,131,1,161,1,1,0,124,3,160,2,116,3, + 124,2,131,1,161,1,1,0,124,3,160,2,116,4,160,5, + 124,0,161,1,161,1,1,0,124,3,83,0,41,2,122,43, + 80,114,111,100,117,99,101,32,116,104,101,32,100,97,116,97, + 32,102,111,114,32,97,32,116,105,109,101,115,116,97,109,112, + 45,98,97,115,101,100,32,112,121,99,46,114,72,0,0,0, + 41,6,218,9,98,121,116,101,97,114,114,97,121,114,148,0, + 0,0,218,6,101,120,116,101,110,100,114,20,0,0,0,114, + 160,0,0,0,218,5,100,117,109,112,115,41,4,114,164,0, + 0,0,218,5,109,116,105,109,101,114,155,0,0,0,114,25, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,22,95,99,111,100,101,95,116,111,95,116,105,109, + 101,115,116,97,109,112,95,112,121,99,82,2,0,0,115,12, + 0,0,0,0,2,8,1,14,1,14,1,14,1,16,1,114, + 170,0,0,0,84,99,3,0,0,0,0,0,0,0,0,0, + 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,80, + 0,0,0,116,0,116,1,131,1,125,3,100,1,124,2,100, + 1,62,0,66,0,125,4,124,3,160,2,116,3,124,4,131, + 1,161,1,1,0,116,4,124,1,131,1,100,2,107,2,115, + 50,74,0,130,1,124,3,160,2,124,1,161,1,1,0,124, + 3,160,2,116,5,160,6,124,0,161,1,161,1,1,0,124, + 3,83,0,41,3,122,38,80,114,111,100,117,99,101,32,116, + 104,101,32,100,97,116,97,32,102,111,114,32,97,32,104,97, + 115,104,45,98,97,115,101,100,32,112,121,99,46,114,38,0, + 0,0,114,146,0,0,0,41,7,114,166,0,0,0,114,148, + 0,0,0,114,167,0,0,0,114,20,0,0,0,114,22,0, + 0,0,114,160,0,0,0,114,168,0,0,0,41,5,114,164, + 0,0,0,114,157,0,0,0,90,7,99,104,101,99,107,101, + 100,114,25,0,0,0,114,82,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,95,99,111,100, + 101,95,116,111,95,104,97,115,104,95,112,121,99,92,2,0, + 0,115,14,0,0,0,0,2,8,1,12,1,14,1,16,1, + 10,1,16,1,114,171,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,6,0,0,0,67,0, + 0,0,115,62,0,0,0,100,1,100,2,108,0,125,1,116, + 1,160,2,124,0,161,1,106,3,125,2,124,1,160,4,124, + 2,161,1,125,3,116,1,160,5,100,2,100,3,161,2,125, + 4,124,4,160,6,124,0,160,6,124,3,100,1,25,0,161, + 1,161,1,83,0,41,4,122,121,68,101,99,111,100,101,32, + 98,121,116,101,115,32,114,101,112,114,101,115,101,110,116,105, + 110,103,32,115,111,117,114,99,101,32,99,111,100,101,32,97, + 110,100,32,114,101,116,117,114,110,32,116,104,101,32,115,116, + 114,105,110,103,46,10,10,32,32,32,32,85,110,105,118,101, + 114,115,97,108,32,110,101,119,108,105,110,101,32,115,117,112, + 112,111,114,116,32,105,115,32,117,115,101,100,32,105,110,32, + 116,104,101,32,100,101,99,111,100,105,110,103,46,10,32,32, + 32,32,114,72,0,0,0,78,84,41,7,218,8,116,111,107, + 101,110,105,122,101,114,63,0,0,0,90,7,66,121,116,101, + 115,73,79,90,8,114,101,97,100,108,105,110,101,90,15,100, + 101,116,101,99,116,95,101,110,99,111,100,105,110,103,90,25, + 73,110,99,114,101,109,101,110,116,97,108,78,101,119,108,105, + 110,101,68,101,99,111,100,101,114,218,6,100,101,99,111,100, + 101,41,5,218,12,115,111,117,114,99,101,95,98,121,116,101, + 115,114,172,0,0,0,90,21,115,111,117,114,99,101,95,98, + 121,116,101,115,95,114,101,97,100,108,105,110,101,218,8,101, + 110,99,111,100,105,110,103,90,15,110,101,119,108,105,110,101, + 95,100,101,99,111,100,101,114,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,13,100,101,99,111,100,101,95, + 115,111,117,114,99,101,103,2,0,0,115,10,0,0,0,0, + 5,8,1,12,1,10,1,12,1,114,176,0,0,0,169,2, + 114,140,0,0,0,218,26,115,117,98,109,111,100,117,108,101, + 95,115,101,97,114,99,104,95,108,111,99,97,116,105,111,110, + 115,99,2,0,0,0,0,0,0,0,2,0,0,0,9,0, + 0,0,8,0,0,0,67,0,0,0,115,16,1,0,0,124, + 1,100,1,107,8,114,60,100,2,125,1,116,0,124,2,100, + 3,131,2,114,70,122,14,124,2,160,1,124,0,161,1,125, + 1,87,0,113,70,4,0,116,2,107,10,114,56,1,0,1, + 0,1,0,89,0,113,70,48,0,110,10,116,3,160,4,124, + 1,161,1,125,1,116,5,106,6,124,0,124,2,124,1,100, + 4,141,3,125,4,100,5,124,4,95,7,124,2,100,1,107, + 8,114,154,116,8,131,0,68,0,93,42,92,2,125,5,125, + 6,124,1,160,9,116,10,124,6,131,1,161,1,114,106,124, + 5,124,0,124,1,131,2,125,2,124,2,124,4,95,11,1, + 0,113,154,113,106,100,1,83,0,124,3,116,12,107,8,114, + 220,116,0,124,2,100,6,131,2,114,226,122,14,124,2,160, + 13,124,0,161,1,125,7,87,0,110,20,4,0,116,2,107, + 10,114,206,1,0,1,0,1,0,89,0,113,226,48,0,124, + 7,114,226,103,0,124,4,95,14,110,6,124,3,124,4,95, + 14,124,4,106,14,103,0,107,2,144,1,114,12,124,1,144, + 1,114,12,116,15,124,1,131,1,100,7,25,0,125,8,124, + 4,106,14,160,16,124,8,161,1,1,0,124,4,83,0,41, + 8,97,61,1,0,0,82,101,116,117,114,110,32,97,32,109, + 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, + 32,111,110,32,97,32,102,105,108,101,32,108,111,99,97,116, + 105,111,110,46,10,10,32,32,32,32,84,111,32,105,110,100, + 105,99,97,116,101,32,116,104,97,116,32,116,104,101,32,109, + 111,100,117,108,101,32,105,115,32,97,32,112,97,99,107,97, + 103,101,44,32,115,101,116,10,32,32,32,32,115,117,98,109, + 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, + 97,116,105,111,110,115,32,116,111,32,97,32,108,105,115,116, + 32,111,102,32,100,105,114,101,99,116,111,114,121,32,112,97, + 116,104,115,46,32,32,65,110,10,32,32,32,32,101,109,112, + 116,121,32,108,105,115,116,32,105,115,32,115,117,102,102,105, + 99,105,101,110,116,44,32,116,104,111,117,103,104,32,105,116, + 115,32,110,111,116,32,111,116,104,101,114,119,105,115,101,32, + 117,115,101,102,117,108,32,116,111,32,116,104,101,10,32,32, + 32,32,105,109,112,111,114,116,32,115,121,115,116,101,109,46, + 10,10,32,32,32,32,84,104,101,32,108,111,97,100,101,114, + 32,109,117,115,116,32,116,97,107,101,32,97,32,115,112,101, + 99,32,97,115,32,105,116,115,32,111,110,108,121,32,95,95, + 105,110,105,116,95,95,40,41,32,97,114,103,46,10,10,32, + 32,32,32,78,122,9,60,117,110,107,110,111,119,110,62,218, + 12,103,101,116,95,102,105,108,101,110,97,109,101,169,1,218, + 6,111,114,105,103,105,110,84,218,10,105,115,95,112,97,99, + 107,97,103,101,114,72,0,0,0,41,17,114,128,0,0,0, + 114,179,0,0,0,114,117,0,0,0,114,2,0,0,0,114, + 78,0,0,0,114,134,0,0,0,218,10,77,111,100,117,108, + 101,83,112,101,99,90,13,95,115,101,116,95,102,105,108,101, + 97,116,116,114,218,27,95,103,101,116,95,115,117,112,112,111, + 114,116,101,100,95,102,105,108,101,95,108,111,97,100,101,114, + 115,114,110,0,0,0,114,111,0,0,0,114,140,0,0,0, + 218,9,95,80,79,80,85,76,65,84,69,114,182,0,0,0, + 114,178,0,0,0,114,46,0,0,0,218,6,97,112,112,101, + 110,100,41,9,114,116,0,0,0,90,8,108,111,99,97,116, + 105,111,110,114,140,0,0,0,114,178,0,0,0,218,4,115, + 112,101,99,218,12,108,111,97,100,101,114,95,99,108,97,115, + 115,218,8,115,117,102,102,105,120,101,115,114,182,0,0,0, + 90,7,100,105,114,110,97,109,101,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,23,115,112,101,99,95,102, + 114,111,109,95,102,105,108,101,95,108,111,99,97,116,105,111, + 110,120,2,0,0,115,62,0,0,0,0,12,8,4,4,1, + 10,2,2,1,14,1,14,1,8,2,10,8,16,1,6,3, + 8,1,14,1,14,1,10,1,6,1,6,2,4,3,8,2, + 10,1,2,1,14,1,14,1,6,2,4,1,8,2,6,1, + 12,1,6,1,12,1,12,2,114,190,0,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,80,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,90,4,100,3,90,5,100, + 4,90,6,101,7,100,5,100,6,132,0,131,1,90,8,101, + 7,100,7,100,8,132,0,131,1,90,9,101,7,100,14,100, + 10,100,11,132,1,131,1,90,10,101,7,100,15,100,12,100, + 13,132,1,131,1,90,11,100,9,83,0,41,16,218,21,87, + 105,110,100,111,119,115,82,101,103,105,115,116,114,121,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,109,111,100,117,108, + 101,115,32,100,101,99,108,97,114,101,100,32,105,110,32,116, + 104,101,32,87,105,110,100,111,119,115,32,114,101,103,105,115, + 116,114,121,46,122,59,83,111,102,116,119,97,114,101,92,80, + 121,116,104,111,110,92,80,121,116,104,111,110,67,111,114,101, + 92,123,115,121,115,95,118,101,114,115,105,111,110,125,92,77, + 111,100,117,108,101,115,92,123,102,117,108,108,110,97,109,101, + 125,122,65,83,111,102,116,119,97,114,101,92,80,121,116,104, + 111,110,92,80,121,116,104,111,110,67,111,114,101,92,123,115, + 121,115,95,118,101,114,115,105,111,110,125,92,77,111,100,117, + 108,101,115,92,123,102,117,108,108,110,97,109,101,125,92,68, + 101,98,117,103,70,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,8,0,0,0,67,0,0,0,115,56, + 0,0,0,122,16,116,0,160,1,116,0,106,2,124,1,161, + 2,87,0,83,0,4,0,116,3,107,10,114,50,1,0,1, + 0,1,0,116,0,160,1,116,0,106,4,124,1,161,2,6, + 0,89,0,83,0,48,0,100,0,83,0,114,109,0,0,0, + 41,5,218,7,95,119,105,110,114,101,103,90,7,79,112,101, + 110,75,101,121,90,17,72,75,69,89,95,67,85,82,82,69, + 78,84,95,85,83,69,82,114,49,0,0,0,90,18,72,75, + 69,89,95,76,79,67,65,76,95,77,65,67,72,73,78,69, + 41,2,218,3,99,108,115,114,5,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,95,111,112, + 101,110,95,114,101,103,105,115,116,114,121,200,2,0,0,115, + 8,0,0,0,0,2,2,1,16,1,14,1,122,36,87,105, + 110,100,111,119,115,82,101,103,105,115,116,114,121,70,105,110, + 100,101,114,46,95,111,112,101,110,95,114,101,103,105,115,116, + 114,121,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,134,0,0,0, + 124,0,106,0,114,14,124,0,106,1,125,2,110,6,124,0, + 106,2,125,2,124,2,106,3,124,1,100,1,116,4,106,5, + 100,0,100,2,133,2,25,0,22,0,100,3,141,2,125,3, + 122,58,124,0,160,6,124,3,161,1,143,28,125,4,116,7, + 160,8,124,4,100,4,161,2,125,5,87,0,100,0,4,0, + 4,0,131,3,1,0,110,16,49,0,115,94,48,0,1,0, + 1,0,1,0,89,0,1,0,87,0,110,22,4,0,116,9, + 107,10,114,128,1,0,1,0,1,0,89,0,100,0,83,0, + 48,0,124,5,83,0,41,5,78,122,5,37,100,46,37,100, + 114,27,0,0,0,41,2,114,139,0,0,0,90,11,115,121, + 115,95,118,101,114,115,105,111,110,114,39,0,0,0,41,10, + 218,11,68,69,66,85,71,95,66,85,73,76,68,218,18,82, + 69,71,73,83,84,82,89,95,75,69,89,95,68,69,66,85, + 71,218,12,82,69,71,73,83,84,82,89,95,75,69,89,114, + 61,0,0,0,114,8,0,0,0,218,12,118,101,114,115,105, + 111,110,95,105,110,102,111,114,194,0,0,0,114,192,0,0, + 0,90,10,81,117,101,114,121,86,97,108,117,101,114,49,0, + 0,0,41,6,114,193,0,0,0,114,139,0,0,0,90,12, + 114,101,103,105,115,116,114,121,95,107,101,121,114,5,0,0, + 0,90,4,104,107,101,121,218,8,102,105,108,101,112,97,116, + 104,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,16,95,115,101,97,114,99,104,95,114,101,103,105,115,116, + 114,121,207,2,0,0,115,24,0,0,0,0,2,6,1,8, + 2,6,1,6,1,16,255,6,2,2,1,12,1,46,1,14, + 1,8,1,122,38,87,105,110,100,111,119,115,82,101,103,105, + 115,116,114,121,70,105,110,100,101,114,46,95,115,101,97,114, + 99,104,95,114,101,103,105,115,116,114,121,78,99,4,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,8,0,0, + 0,67,0,0,0,115,122,0,0,0,124,0,160,0,124,1, + 161,1,125,4,124,4,100,0,107,8,114,22,100,0,83,0, + 122,12,116,1,124,4,131,1,1,0,87,0,110,22,4,0, + 116,2,107,10,114,56,1,0,1,0,1,0,89,0,100,0, + 83,0,48,0,116,3,131,0,68,0,93,52,92,2,125,5, + 125,6,124,4,160,4,116,5,124,6,131,1,161,1,114,64, + 116,6,106,7,124,1,124,5,124,1,124,4,131,2,124,4, + 100,1,141,3,125,7,124,7,2,0,1,0,83,0,113,64, + 100,0,83,0,41,2,78,114,180,0,0,0,41,8,114,200, + 0,0,0,114,48,0,0,0,114,49,0,0,0,114,184,0, + 0,0,114,110,0,0,0,114,111,0,0,0,114,134,0,0, + 0,218,16,115,112,101,99,95,102,114,111,109,95,108,111,97, + 100,101,114,41,8,114,193,0,0,0,114,139,0,0,0,114, + 43,0,0,0,218,6,116,97,114,103,101,116,114,199,0,0, + 0,114,140,0,0,0,114,189,0,0,0,114,187,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 15,95,99,97,99,104,101,95,98,121,116,101,99,111,100,101, - 47,3,0,0,115,2,0,0,0,0,8,122,28,83,111,117, - 114,99,101,76,111,97,100,101,114,46,95,99,97,99,104,101, - 95,98,121,116,101,99,111,100,101,99,3,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,1,83,0,41,2,122,150,79, - 112,116,105,111,110,97,108,32,109,101,116,104,111,100,32,119, - 104,105,99,104,32,119,114,105,116,101,115,32,100,97,116,97, - 32,40,98,121,116,101,115,41,32,116,111,32,97,32,102,105, - 108,101,32,112,97,116,104,32,40,97,32,115,116,114,41,46, + 9,102,105,110,100,95,115,112,101,99,222,2,0,0,115,28, + 0,0,0,0,2,10,1,8,1,4,1,2,1,12,1,14, + 1,8,1,14,1,14,1,6,1,8,1,2,254,6,3,122, + 31,87,105,110,100,111,119,115,82,101,103,105,115,116,114,121, + 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,34,0,0,0,124,0, + 160,0,124,1,124,2,161,2,125,3,124,3,100,1,107,9, + 114,26,124,3,106,1,83,0,100,1,83,0,100,1,83,0, + 41,2,122,108,70,105,110,100,32,109,111,100,117,108,101,32, + 110,97,109,101,100,32,105,110,32,116,104,101,32,114,101,103, + 105,115,116,114,121,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, + 78,169,2,114,203,0,0,0,114,140,0,0,0,169,4,114, + 193,0,0,0,114,139,0,0,0,114,43,0,0,0,114,187, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,11,102,105,110,100,95,109,111,100,117,108,101,238, + 2,0,0,115,8,0,0,0,0,7,12,1,8,1,6,2, + 122,33,87,105,110,100,111,119,115,82,101,103,105,115,116,114, + 121,70,105,110,100,101,114,46,102,105,110,100,95,109,111,100, + 117,108,101,41,2,78,78,41,1,78,41,12,114,125,0,0, + 0,114,124,0,0,0,114,126,0,0,0,114,127,0,0,0, + 114,197,0,0,0,114,196,0,0,0,114,195,0,0,0,218, + 11,99,108,97,115,115,109,101,116,104,111,100,114,194,0,0, + 0,114,200,0,0,0,114,203,0,0,0,114,206,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,191,0,0,0,188,2,0,0,115,28,0, + 0,0,8,2,4,3,2,255,2,4,2,255,2,3,4,2, + 2,1,10,6,2,1,10,14,2,1,12,15,2,1,114,191, + 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,48,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,83, + 0,41,11,218,13,95,76,111,97,100,101,114,66,97,115,105, + 99,115,122,83,66,97,115,101,32,99,108,97,115,115,32,111, + 102,32,99,111,109,109,111,110,32,99,111,100,101,32,110,101, + 101,100,101,100,32,98,121,32,98,111,116,104,32,83,111,117, + 114,99,101,76,111,97,100,101,114,32,97,110,100,10,32,32, + 32,32,83,111,117,114,99,101,108,101,115,115,70,105,108,101, + 76,111,97,100,101,114,46,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,4,0,0,0,67,0,0,0, + 115,64,0,0,0,116,0,124,0,160,1,124,1,161,1,131, + 1,100,1,25,0,125,2,124,2,160,2,100,2,100,1,161, + 2,100,3,25,0,125,3,124,1,160,3,100,2,161,1,100, + 4,25,0,125,4,124,3,100,5,107,2,111,62,124,4,100, + 5,107,3,83,0,41,6,122,141,67,111,110,99,114,101,116, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,73,110,115,112,101,99,116,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,101,32,98,121,32, + 99,104,101,99,107,105,110,103,32,105,102,10,32,32,32,32, + 32,32,32,32,116,104,101,32,112,97,116,104,32,114,101,116, + 117,114,110,101,100,32,98,121,32,103,101,116,95,102,105,108, + 101,110,97,109,101,32,104,97,115,32,97,32,102,105,108,101, + 110,97,109,101,32,111,102,32,39,95,95,105,110,105,116,95, + 95,46,112,121,39,46,114,38,0,0,0,114,70,0,0,0, + 114,72,0,0,0,114,27,0,0,0,218,8,95,95,105,110, + 105,116,95,95,41,4,114,46,0,0,0,114,179,0,0,0, + 114,42,0,0,0,114,40,0,0,0,41,5,114,118,0,0, + 0,114,139,0,0,0,114,96,0,0,0,90,13,102,105,108, + 101,110,97,109,101,95,98,97,115,101,90,9,116,97,105,108, + 95,110,97,109,101,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,182,0,0,0,1,3,0,0,115,8,0, + 0,0,0,3,18,1,16,1,14,1,122,24,95,76,111,97, + 100,101,114,66,97,115,105,99,115,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,169,2,122,42,85,115,101,32,100,101, + 102,97,117,108,116,32,115,101,109,97,110,116,105,99,115,32, + 102,111,114,32,109,111,100,117,108,101,32,99,114,101,97,116, + 105,111,110,46,78,114,3,0,0,0,169,2,114,118,0,0, + 0,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,13,99,114,101,97,116,101,95,109,111, + 100,117,108,101,9,3,0,0,115,2,0,0,0,0,1,122, + 27,95,76,111,97,100,101,114,66,97,115,105,99,115,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,3,0,0,0,5,0,0, + 0,67,0,0,0,115,56,0,0,0,124,0,160,0,124,1, + 106,1,161,1,125,2,124,2,100,1,107,8,114,36,116,2, + 100,2,160,3,124,1,106,1,161,1,131,1,130,1,116,4, + 160,5,116,6,124,2,124,1,106,7,161,3,1,0,100,1, + 83,0,41,3,122,19,69,120,101,99,117,116,101,32,116,104, + 101,32,109,111,100,117,108,101,46,78,122,52,99,97,110,110, + 111,116,32,108,111,97,100,32,109,111,100,117,108,101,32,123, + 33,114,125,32,119,104,101,110,32,103,101,116,95,99,111,100, + 101,40,41,32,114,101,116,117,114,110,115,32,78,111,110,101, + 41,8,218,8,103,101,116,95,99,111,100,101,114,125,0,0, + 0,114,117,0,0,0,114,61,0,0,0,114,134,0,0,0, + 218,25,95,99,97,108,108,95,119,105,116,104,95,102,114,97, + 109,101,115,95,114,101,109,111,118,101,100,218,4,101,120,101, + 99,114,131,0,0,0,41,3,114,118,0,0,0,218,6,109, + 111,100,117,108,101,114,164,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,11,101,120,101,99,95, + 109,111,100,117,108,101,12,3,0,0,115,12,0,0,0,0, + 2,12,1,8,1,6,1,4,255,6,2,122,25,95,76,111, + 97,100,101,114,66,97,115,105,99,115,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, + 12,0,0,0,116,0,160,1,124,0,124,1,161,2,83,0, + 41,1,122,26,84,104,105,115,32,109,111,100,117,108,101,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,41,2, + 114,134,0,0,0,218,17,95,108,111,97,100,95,109,111,100, + 117,108,101,95,115,104,105,109,169,2,114,118,0,0,0,114, + 139,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, + 20,3,0,0,115,2,0,0,0,0,2,122,25,95,76,111, + 97,100,101,114,66,97,115,105,99,115,46,108,111,97,100,95, + 109,111,100,117,108,101,78,41,8,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,182,0, + 0,0,114,212,0,0,0,114,217,0,0,0,114,220,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,208,0,0,0,252,2,0,0,115,10, + 0,0,0,8,2,4,3,8,8,8,3,8,8,114,208,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,74,0,0,0, + 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, + 100,3,100,4,132,0,90,4,100,5,100,6,132,0,90,5, + 100,7,100,8,132,0,90,6,100,9,100,10,132,0,90,7, + 100,11,100,12,156,1,100,13,100,14,132,2,90,8,100,15, + 100,16,132,0,90,9,100,17,83,0,41,18,218,12,83,111, + 117,114,99,101,76,111,97,100,101,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,8,0,0,0,116,0,130,1,100,1,83,0, + 41,2,122,165,79,112,116,105,111,110,97,108,32,109,101,116, + 104,111,100,32,116,104,97,116,32,114,101,116,117,114,110,115, + 32,116,104,101,32,109,111,100,105,102,105,99,97,116,105,111, + 110,32,116,105,109,101,32,40,97,110,32,105,110,116,41,32, + 102,111,114,32,116,104,101,10,32,32,32,32,32,32,32,32, + 115,112,101,99,105,102,105,101,100,32,112,97,116,104,32,40, + 97,32,115,116,114,41,46,10,10,32,32,32,32,32,32,32, + 32,82,97,105,115,101,115,32,79,83,69,114,114,111,114,32, + 119,104,101,110,32,116,104,101,32,112,97,116,104,32,99,97, + 110,110,111,116,32,98,101,32,104,97,110,100,108,101,100,46, + 10,32,32,32,32,32,32,32,32,78,41,1,114,49,0,0, + 0,169,2,114,118,0,0,0,114,43,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,10,112,97, + 116,104,95,109,116,105,109,101,27,3,0,0,115,2,0,0, + 0,0,6,122,23,83,111,117,114,99,101,76,111,97,100,101, + 114,46,112,97,116,104,95,109,116,105,109,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,14,0,0,0,100,1,124,0,160,0, + 124,1,161,1,105,1,83,0,41,2,97,158,1,0,0,79, + 112,116,105,111,110,97,108,32,109,101,116,104,111,100,32,114, + 101,116,117,114,110,105,110,103,32,97,32,109,101,116,97,100, + 97,116,97,32,100,105,99,116,32,102,111,114,32,116,104,101, + 32,115,112,101,99,105,102,105,101,100,10,32,32,32,32,32, + 32,32,32,112,97,116,104,32,40,97,32,115,116,114,41,46, + 10,10,32,32,32,32,32,32,32,32,80,111,115,115,105,98, + 108,101,32,107,101,121,115,58,10,32,32,32,32,32,32,32, + 32,45,32,39,109,116,105,109,101,39,32,40,109,97,110,100, + 97,116,111,114,121,41,32,105,115,32,116,104,101,32,110,117, + 109,101,114,105,99,32,116,105,109,101,115,116,97,109,112,32, + 111,102,32,108,97,115,116,32,115,111,117,114,99,101,10,32, + 32,32,32,32,32,32,32,32,32,99,111,100,101,32,109,111, + 100,105,102,105,99,97,116,105,111,110,59,10,32,32,32,32, + 32,32,32,32,45,32,39,115,105,122,101,39,32,40,111,112, + 116,105,111,110,97,108,41,32,105,115,32,116,104,101,32,115, + 105,122,101,32,105,110,32,98,121,116,101,115,32,111,102,32, + 116,104,101,32,115,111,117,114,99,101,32,99,111,100,101,46, 10,10,32,32,32,32,32,32,32,32,73,109,112,108,101,109, 101,110,116,105,110,103,32,116,104,105,115,32,109,101,116,104, - 111,100,32,97,108,108,111,119,115,32,102,111,114,32,116,104, - 101,32,119,114,105,116,105,110,103,32,111,102,32,98,121,116, + 111,100,32,97,108,108,111,119,115,32,116,104,101,32,108,111, + 97,100,101,114,32,116,111,32,114,101,97,100,32,98,121,116, 101,99,111,100,101,32,102,105,108,101,115,46,10,32,32,32, - 32,32,32,32,32,78,114,3,0,0,0,41,3,114,118,0, - 0,0,114,43,0,0,0,114,25,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,225,0,0,0, - 57,3,0,0,115,2,0,0,0,0,1,122,21,83,111,117, - 114,99,101,76,111,97,100,101,114,46,115,101,116,95,100,97, - 116,97,99,2,0,0,0,0,0,0,0,0,0,0,0,5, - 0,0,0,10,0,0,0,67,0,0,0,115,82,0,0,0, - 124,0,160,0,124,1,161,1,125,2,122,14,124,0,160,1, - 124,2,161,1,125,3,87,0,110,48,4,0,116,2,107,10, - 114,72,1,0,125,4,1,0,122,18,116,3,100,1,124,1, - 100,2,141,2,124,4,130,2,87,0,53,0,100,3,125,4, - 126,4,88,0,89,0,110,2,88,0,116,4,124,3,131,1, - 83,0,41,4,122,52,67,111,110,99,114,101,116,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,103, - 101,116,95,115,111,117,114,99,101,46,122,39,115,111,117,114, - 99,101,32,110,111,116,32,97,118,97,105,108,97,98,108,101, - 32,116,104,114,111,117,103,104,32,103,101,116,95,100,97,116, - 97,40,41,114,115,0,0,0,78,41,5,114,179,0,0,0, - 218,8,103,101,116,95,100,97,116,97,114,49,0,0,0,114, - 117,0,0,0,114,176,0,0,0,41,5,114,118,0,0,0, - 114,139,0,0,0,114,43,0,0,0,114,174,0,0,0,218, - 3,101,120,99,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,10,103,101,116,95,115,111,117,114,99,101,64, - 3,0,0,115,20,0,0,0,0,2,10,1,2,1,14,1, - 16,1,4,1,2,255,4,1,2,255,20,2,122,23,83,111, - 117,114,99,101,76,111,97,100,101,114,46,103,101,116,95,115, - 111,117,114,99,101,114,104,0,0,0,41,1,218,9,95,111, - 112,116,105,109,105,122,101,99,3,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,8,0,0,0,67,0,0,0, - 115,22,0,0,0,116,0,106,1,116,2,124,1,124,2,100, - 1,100,2,124,3,100,3,141,6,83,0,41,4,122,130,82, - 101,116,117,114,110,32,116,104,101,32,99,111,100,101,32,111, - 98,106,101,99,116,32,99,111,109,112,105,108,101,100,32,102, - 114,111,109,32,115,111,117,114,99,101,46,10,10,32,32,32, - 32,32,32,32,32,84,104,101,32,39,100,97,116,97,39,32, - 97,114,103,117,109,101,110,116,32,99,97,110,32,98,101,32, - 97,110,121,32,111,98,106,101,99,116,32,116,121,112,101,32, - 116,104,97,116,32,99,111,109,112,105,108,101,40,41,32,115, - 117,112,112,111,114,116,115,46,10,32,32,32,32,32,32,32, - 32,114,215,0,0,0,84,41,2,218,12,100,111,110,116,95, - 105,110,104,101,114,105,116,114,83,0,0,0,41,3,114,134, - 0,0,0,114,214,0,0,0,218,7,99,111,109,112,105,108, - 101,41,4,114,118,0,0,0,114,25,0,0,0,114,43,0, - 0,0,114,230,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,14,115,111,117,114,99,101,95,116, - 111,95,99,111,100,101,74,3,0,0,115,8,0,0,0,0, - 5,12,1,2,0,2,255,122,27,83,111,117,114,99,101,76, - 111,97,100,101,114,46,115,111,117,114,99,101,95,116,111,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,0,0,0, - 0,15,0,0,0,9,0,0,0,67,0,0,0,115,34,2, - 0,0,124,0,160,0,124,1,161,1,125,2,100,1,125,3, - 100,1,125,4,100,1,125,5,100,2,125,6,100,3,125,7, - 122,12,116,1,124,2,131,1,125,8,87,0,110,26,4,0, - 116,2,107,10,114,68,1,0,1,0,1,0,100,1,125,8, - 89,0,144,1,110,48,88,0,122,14,124,0,160,3,124,2, - 161,1,125,9,87,0,110,22,4,0,116,4,107,10,114,106, - 1,0,1,0,1,0,89,0,144,1,110,10,88,0,116,5, - 124,9,100,4,25,0,131,1,125,3,122,14,124,0,160,6, - 124,8,161,1,125,10,87,0,110,20,4,0,116,4,107,10, - 114,154,1,0,1,0,1,0,89,0,110,218,88,0,124,1, - 124,8,100,5,156,2,125,11,122,148,116,7,124,10,124,1, - 124,11,131,3,125,12,116,8,124,10,131,1,100,6,100,1, - 133,2,25,0,125,13,124,12,100,7,64,0,100,8,107,3, - 125,6,124,6,144,1,114,36,124,12,100,9,64,0,100,8, - 107,3,125,7,116,9,106,10,100,10,107,3,144,1,114,56, - 124,7,115,254,116,9,106,10,100,11,107,2,144,1,114,56, - 124,0,160,6,124,2,161,1,125,4,116,9,160,11,116,12, - 124,4,161,2,125,5,116,13,124,10,124,5,124,1,124,11, - 131,4,1,0,110,20,116,14,124,10,124,3,124,9,100,12, - 25,0,124,1,124,11,131,5,1,0,87,0,110,26,4,0, - 116,15,116,16,102,2,107,10,144,1,114,84,1,0,1,0, - 1,0,89,0,110,32,88,0,116,17,160,18,100,13,124,8, - 124,2,161,3,1,0,116,19,124,13,124,1,124,8,124,2, - 100,14,141,4,83,0,124,4,100,1,107,8,144,1,114,136, - 124,0,160,6,124,2,161,1,125,4,124,0,160,20,124,4, - 124,2,161,2,125,14,116,17,160,18,100,15,124,2,161,2, - 1,0,116,21,106,22,144,2,115,30,124,8,100,1,107,9, - 144,2,114,30,124,3,100,1,107,9,144,2,114,30,124,6, - 144,1,114,228,124,5,100,1,107,8,144,1,114,214,116,9, - 160,11,124,4,161,1,125,5,116,23,124,14,124,5,124,7, - 131,3,125,10,110,16,116,24,124,14,124,3,116,25,124,4, - 131,1,131,3,125,10,122,18,124,0,160,26,124,2,124,8, - 124,10,161,3,1,0,87,0,110,22,4,0,116,2,107,10, - 144,2,114,28,1,0,1,0,1,0,89,0,110,2,88,0, - 124,14,83,0,41,16,122,190,67,111,110,99,114,101,116,101, - 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32, - 111,102,32,73,110,115,112,101,99,116,76,111,97,100,101,114, - 46,103,101,116,95,99,111,100,101,46,10,10,32,32,32,32, - 32,32,32,32,82,101,97,100,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,114,101,113,117,105,114,101,115, - 32,112,97,116,104,95,115,116,97,116,115,32,116,111,32,98, - 101,32,105,109,112,108,101,109,101,110,116,101,100,46,32,84, - 111,32,119,114,105,116,101,10,32,32,32,32,32,32,32,32, - 98,121,116,101,99,111,100,101,44,32,115,101,116,95,100,97, - 116,97,32,109,117,115,116,32,97,108,115,111,32,98,101,32, - 105,109,112,108,101,109,101,110,116,101,100,46,10,10,32,32, - 32,32,32,32,32,32,78,70,84,114,169,0,0,0,114,159, - 0,0,0,114,145,0,0,0,114,38,0,0,0,114,72,0, - 0,0,114,27,0,0,0,90,5,110,101,118,101,114,90,6, - 97,108,119,97,121,115,218,4,115,105,122,101,122,13,123,125, - 32,109,97,116,99,104,101,115,32,123,125,41,3,114,116,0, - 0,0,114,106,0,0,0,114,107,0,0,0,122,19,99,111, - 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, - 125,41,27,114,179,0,0,0,114,97,0,0,0,114,81,0, - 0,0,114,224,0,0,0,114,49,0,0,0,114,17,0,0, - 0,114,227,0,0,0,114,152,0,0,0,218,10,109,101,109, - 111,114,121,118,105,101,119,114,163,0,0,0,90,21,99,104, - 101,99,107,95,104,97,115,104,95,98,97,115,101,100,95,112, - 121,99,115,114,157,0,0,0,218,17,95,82,65,87,95,77, - 65,71,73,67,95,78,85,77,66,69,82,114,158,0,0,0, - 114,156,0,0,0,114,117,0,0,0,114,150,0,0,0,114, - 134,0,0,0,114,149,0,0,0,114,165,0,0,0,114,233, - 0,0,0,114,8,0,0,0,218,19,100,111,110,116,95,119, - 114,105,116,101,95,98,121,116,101,99,111,100,101,114,171,0, - 0,0,114,170,0,0,0,114,22,0,0,0,114,226,0,0, - 0,41,15,114,118,0,0,0,114,139,0,0,0,114,107,0, - 0,0,114,154,0,0,0,114,174,0,0,0,114,157,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,114,106,0,0,0, - 218,2,115,116,114,25,0,0,0,114,151,0,0,0,114,82, - 0,0,0,90,10,98,121,116,101,115,95,100,97,116,97,90, - 11,99,111,100,101,95,111,98,106,101,99,116,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,213,0,0,0, - 82,3,0,0,115,152,0,0,0,0,7,10,1,4,1,4, - 1,4,1,4,1,4,1,2,1,12,1,14,1,12,2,2, - 1,14,1,14,1,8,2,12,1,2,1,14,1,14,1,6, - 3,2,1,2,254,6,4,2,1,12,1,16,1,12,1,6, - 1,12,1,12,1,2,255,2,2,8,254,4,3,10,1,4, - 1,2,1,2,254,4,4,8,1,2,255,6,3,2,1,2, - 1,2,1,6,1,2,1,2,251,8,7,20,1,6,2,8, - 1,2,255,4,2,6,1,2,1,2,254,6,3,10,1,10, - 1,12,1,12,1,18,1,6,255,4,2,6,1,10,1,10, - 1,14,2,6,1,6,255,4,2,2,1,18,1,16,1,6, - 1,122,21,83,111,117,114,99,101,76,111,97,100,101,114,46, - 103,101,116,95,99,111,100,101,78,41,10,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,223,0,0,0,114, - 224,0,0,0,114,226,0,0,0,114,225,0,0,0,114,229, - 0,0,0,114,233,0,0,0,114,213,0,0,0,114,3,0, + 32,32,32,32,32,82,97,105,115,101,115,32,79,83,69,114, + 114,111,114,32,119,104,101,110,32,116,104,101,32,112,97,116, + 104,32,99,97,110,110,111,116,32,98,101,32,104,97,110,100, + 108,101,100,46,10,32,32,32,32,32,32,32,32,114,169,0, + 0,0,41,1,114,223,0,0,0,114,222,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,10,112, + 97,116,104,95,115,116,97,116,115,35,3,0,0,115,2,0, + 0,0,0,12,122,23,83,111,117,114,99,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,0,0,0,4,0,0,0,4,0, + 0,0,67,0,0,0,115,12,0,0,0,124,0,160,0,124, + 2,124,3,161,2,83,0,41,1,122,228,79,112,116,105,111, + 110,97,108,32,109,101,116,104,111,100,32,119,104,105,99,104, + 32,119,114,105,116,101,115,32,100,97,116,97,32,40,98,121, + 116,101,115,41,32,116,111,32,97,32,102,105,108,101,32,112, + 97,116,104,32,40,97,32,115,116,114,41,46,10,10,32,32, + 32,32,32,32,32,32,73,109,112,108,101,109,101,110,116,105, + 110,103,32,116,104,105,115,32,109,101,116,104,111,100,32,97, + 108,108,111,119,115,32,102,111,114,32,116,104,101,32,119,114, + 105,116,105,110,103,32,111,102,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,115,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,115,111,117,114,99,101,32,112,97,116, + 104,32,105,115,32,110,101,101,100,101,100,32,105,110,32,111, + 114,100,101,114,32,116,111,32,99,111,114,114,101,99,116,108, + 121,32,116,114,97,110,115,102,101,114,32,112,101,114,109,105, + 115,115,105,111,110,115,10,32,32,32,32,32,32,32,32,41, + 1,218,8,115,101,116,95,100,97,116,97,41,4,114,118,0, + 0,0,114,107,0,0,0,90,10,99,97,99,104,101,95,112, + 97,116,104,114,25,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,15,95,99,97,99,104,101,95, + 98,121,116,101,99,111,100,101,49,3,0,0,115,2,0,0, + 0,0,8,122,28,83,111,117,114,99,101,76,111,97,100,101, + 114,46,95,99,97,99,104,101,95,98,121,116,101,99,111,100, + 101,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,83,0,41,2,122,150,79,112,116,105,111,110,97,108,32, + 109,101,116,104,111,100,32,119,104,105,99,104,32,119,114,105, + 116,101,115,32,100,97,116,97,32,40,98,121,116,101,115,41, + 32,116,111,32,97,32,102,105,108,101,32,112,97,116,104,32, + 40,97,32,115,116,114,41,46,10,10,32,32,32,32,32,32, + 32,32,73,109,112,108,101,109,101,110,116,105,110,103,32,116, + 104,105,115,32,109,101,116,104,111,100,32,97,108,108,111,119, + 115,32,102,111,114,32,116,104,101,32,119,114,105,116,105,110, + 103,32,111,102,32,98,121,116,101,99,111,100,101,32,102,105, + 108,101,115,46,10,32,32,32,32,32,32,32,32,78,114,3, + 0,0,0,41,3,114,118,0,0,0,114,43,0,0,0,114, + 25,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,225,0,0,0,59,3,0,0,115,2,0,0, + 0,0,1,122,21,83,111,117,114,99,101,76,111,97,100,101, + 114,46,115,101,116,95,100,97,116,97,99,2,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,10,0,0,0,67, + 0,0,0,115,86,0,0,0,124,0,160,0,124,1,161,1, + 125,2,122,14,124,0,160,1,124,2,161,1,125,3,87,0, + 110,52,4,0,116,2,107,10,114,76,1,0,125,4,1,0, + 122,26,116,3,100,1,124,1,100,2,141,2,124,4,130,2, + 87,0,89,0,100,3,125,4,126,4,110,10,100,3,125,4, + 126,4,48,0,48,0,116,4,124,3,131,1,83,0,41,4, + 122,52,67,111,110,99,114,101,116,101,32,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,32,111,102,32,73,110,115, + 112,101,99,116,76,111,97,100,101,114,46,103,101,116,95,115, + 111,117,114,99,101,46,122,39,115,111,117,114,99,101,32,110, + 111,116,32,97,118,97,105,108,97,98,108,101,32,116,104,114, + 111,117,103,104,32,103,101,116,95,100,97,116,97,40,41,114, + 115,0,0,0,78,41,5,114,179,0,0,0,218,8,103,101, + 116,95,100,97,116,97,114,49,0,0,0,114,117,0,0,0, + 114,176,0,0,0,41,5,114,118,0,0,0,114,139,0,0, + 0,114,43,0,0,0,114,174,0,0,0,218,3,101,120,99, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 10,103,101,116,95,115,111,117,114,99,101,66,3,0,0,115, + 20,0,0,0,0,2,10,1,2,1,14,1,16,1,4,1, + 2,255,4,1,2,255,24,2,122,23,83,111,117,114,99,101, + 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99, + 101,114,104,0,0,0,41,1,218,9,95,111,112,116,105,109, + 105,122,101,99,3,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,8,0,0,0,67,0,0,0,115,22,0,0, + 0,116,0,106,1,116,2,124,1,124,2,100,1,100,2,124, + 3,100,3,141,6,83,0,41,4,122,130,82,101,116,117,114, + 110,32,116,104,101,32,99,111,100,101,32,111,98,106,101,99, + 116,32,99,111,109,112,105,108,101,100,32,102,114,111,109,32, + 115,111,117,114,99,101,46,10,10,32,32,32,32,32,32,32, + 32,84,104,101,32,39,100,97,116,97,39,32,97,114,103,117, + 109,101,110,116,32,99,97,110,32,98,101,32,97,110,121,32, + 111,98,106,101,99,116,32,116,121,112,101,32,116,104,97,116, + 32,99,111,109,112,105,108,101,40,41,32,115,117,112,112,111, + 114,116,115,46,10,32,32,32,32,32,32,32,32,114,215,0, + 0,0,84,41,2,218,12,100,111,110,116,95,105,110,104,101, + 114,105,116,114,83,0,0,0,41,3,114,134,0,0,0,114, + 214,0,0,0,218,7,99,111,109,112,105,108,101,41,4,114, + 118,0,0,0,114,25,0,0,0,114,43,0,0,0,114,230, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,14,115,111,117,114,99,101,95,116,111,95,99,111, + 100,101,76,3,0,0,115,8,0,0,0,0,5,12,1,2, + 0,2,255,122,27,83,111,117,114,99,101,76,111,97,100,101, + 114,46,115,111,117,114,99,101,95,116,111,95,99,111,100,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,15,0,0, + 0,9,0,0,0,67,0,0,0,115,34,2,0,0,124,0, + 160,0,124,1,161,1,125,2,100,1,125,3,100,1,125,4, + 100,1,125,5,100,2,125,6,100,3,125,7,122,12,116,1, + 124,2,131,1,125,8,87,0,110,26,4,0,116,2,107,10, + 114,68,1,0,1,0,1,0,100,1,125,8,89,0,144,1, + 110,48,48,0,122,14,124,0,160,3,124,2,161,1,125,9, + 87,0,110,22,4,0,116,4,107,10,114,106,1,0,1,0, + 1,0,89,0,144,1,110,10,48,0,116,5,124,9,100,4, + 25,0,131,1,125,3,122,14,124,0,160,6,124,8,161,1, + 125,10,87,0,110,20,4,0,116,4,107,10,114,154,1,0, + 1,0,1,0,89,0,110,218,48,0,124,1,124,8,100,5, + 156,2,125,11,122,148,116,7,124,10,124,1,124,11,131,3, + 125,12,116,8,124,10,131,1,100,6,100,1,133,2,25,0, + 125,13,124,12,100,7,64,0,100,8,107,3,125,6,124,6, + 144,1,114,36,124,12,100,9,64,0,100,8,107,3,125,7, + 116,9,106,10,100,10,107,3,144,1,114,56,124,7,115,254, + 116,9,106,10,100,11,107,2,144,1,114,56,124,0,160,6, + 124,2,161,1,125,4,116,9,160,11,116,12,124,4,161,2, + 125,5,116,13,124,10,124,5,124,1,124,11,131,4,1,0, + 110,20,116,14,124,10,124,3,124,9,100,12,25,0,124,1, + 124,11,131,5,1,0,87,0,110,26,4,0,116,15,116,16, + 102,2,107,10,144,1,114,84,1,0,1,0,1,0,89,0, + 110,32,48,0,116,17,160,18,100,13,124,8,124,2,161,3, + 1,0,116,19,124,13,124,1,124,8,124,2,100,14,141,4, + 83,0,124,4,100,1,107,8,144,1,114,136,124,0,160,6, + 124,2,161,1,125,4,124,0,160,20,124,4,124,2,161,2, + 125,14,116,17,160,18,100,15,124,2,161,2,1,0,116,21, + 106,22,144,2,115,30,124,8,100,1,107,9,144,2,114,30, + 124,3,100,1,107,9,144,2,114,30,124,6,144,1,114,228, + 124,5,100,1,107,8,144,1,114,214,116,9,160,11,124,4, + 161,1,125,5,116,23,124,14,124,5,124,7,131,3,125,10, + 110,16,116,24,124,14,124,3,116,25,124,4,131,1,131,3, + 125,10,122,18,124,0,160,26,124,2,124,8,124,10,161,3, + 1,0,87,0,110,22,4,0,116,2,107,10,144,2,114,28, + 1,0,1,0,1,0,89,0,110,2,48,0,124,14,83,0, + 41,16,122,190,67,111,110,99,114,101,116,101,32,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,73, + 110,115,112,101,99,116,76,111,97,100,101,114,46,103,101,116, + 95,99,111,100,101,46,10,10,32,32,32,32,32,32,32,32, + 82,101,97,100,105,110,103,32,111,102,32,98,121,116,101,99, + 111,100,101,32,114,101,113,117,105,114,101,115,32,112,97,116, + 104,95,115,116,97,116,115,32,116,111,32,98,101,32,105,109, + 112,108,101,109,101,110,116,101,100,46,32,84,111,32,119,114, + 105,116,101,10,32,32,32,32,32,32,32,32,98,121,116,101, + 99,111,100,101,44,32,115,101,116,95,100,97,116,97,32,109, + 117,115,116,32,97,108,115,111,32,98,101,32,105,109,112,108, + 101,109,101,110,116,101,100,46,10,10,32,32,32,32,32,32, + 32,32,78,70,84,114,169,0,0,0,114,159,0,0,0,114, + 145,0,0,0,114,38,0,0,0,114,72,0,0,0,114,27, + 0,0,0,90,5,110,101,118,101,114,90,6,97,108,119,97, + 121,115,218,4,115,105,122,101,122,13,123,125,32,109,97,116, + 99,104,101,115,32,123,125,41,3,114,116,0,0,0,114,106, + 0,0,0,114,107,0,0,0,122,19,99,111,100,101,32,111, + 98,106,101,99,116,32,102,114,111,109,32,123,125,41,27,114, + 179,0,0,0,114,97,0,0,0,114,81,0,0,0,114,224, + 0,0,0,114,49,0,0,0,114,17,0,0,0,114,227,0, + 0,0,114,152,0,0,0,218,10,109,101,109,111,114,121,118, + 105,101,119,114,163,0,0,0,90,21,99,104,101,99,107,95, + 104,97,115,104,95,98,97,115,101,100,95,112,121,99,115,114, + 157,0,0,0,218,17,95,82,65,87,95,77,65,71,73,67, + 95,78,85,77,66,69,82,114,158,0,0,0,114,156,0,0, + 0,114,117,0,0,0,114,150,0,0,0,114,134,0,0,0, + 114,149,0,0,0,114,165,0,0,0,114,233,0,0,0,114, + 8,0,0,0,218,19,100,111,110,116,95,119,114,105,116,101, + 95,98,121,116,101,99,111,100,101,114,171,0,0,0,114,170, + 0,0,0,114,22,0,0,0,114,226,0,0,0,41,15,114, + 118,0,0,0,114,139,0,0,0,114,107,0,0,0,114,154, + 0,0,0,114,174,0,0,0,114,157,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,114,106,0,0,0,218,2,115,116, + 114,25,0,0,0,114,151,0,0,0,114,82,0,0,0,90, + 10,98,121,116,101,115,95,100,97,116,97,90,11,99,111,100, + 101,95,111,98,106,101,99,116,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,213,0,0,0,84,3,0,0, + 115,152,0,0,0,0,7,10,1,4,1,4,1,4,1,4, + 1,4,1,2,1,12,1,14,1,12,2,2,1,14,1,14, + 1,8,2,12,1,2,1,14,1,14,1,6,3,2,1,2, + 254,6,4,2,1,12,1,16,1,12,1,6,1,12,1,12, + 1,2,255,2,2,8,254,4,3,10,1,4,1,2,1,2, + 254,4,4,8,1,2,255,6,3,2,1,2,1,2,1,6, + 1,2,1,2,251,8,7,20,1,6,2,8,1,2,255,4, + 2,6,1,2,1,2,254,6,3,10,1,10,1,12,1,12, + 1,18,1,6,255,4,2,6,1,10,1,10,1,14,2,6, + 1,6,255,4,2,2,1,18,1,16,1,6,1,122,21,83, + 111,117,114,99,101,76,111,97,100,101,114,46,103,101,116,95, + 99,111,100,101,78,41,10,114,125,0,0,0,114,124,0,0, + 0,114,126,0,0,0,114,223,0,0,0,114,224,0,0,0, + 114,226,0,0,0,114,225,0,0,0,114,229,0,0,0,114, + 233,0,0,0,114,213,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,221,0, + 0,0,25,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, + 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, + 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, + 116,104,101,32,108,111,97,100,101,114,32,112,114,111,116,111, + 99,111,108,32,109,101,116,104,111,100,115,32,116,104,97,116, + 10,32,32,32,32,114,101,113,117,105,114,101,32,102,105,108, + 101,32,115,121,115,116,101,109,32,117,115,97,103,101,46,99, + 3,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,1,83,0,41,2,122, + 75,67,97,99,104,101,32,116,104,101,32,109,111,100,117,108, + 101,32,110,97,109,101,32,97,110,100,32,116,104,101,32,112, + 97,116,104,32,116,111,32,116,104,101,32,102,105,108,101,32, + 102,111,117,110,100,32,98,121,32,116,104,101,10,32,32,32, + 32,32,32,32,32,102,105,110,100,101,114,46,78,114,159,0, + 0,0,41,3,114,118,0,0,0,114,139,0,0,0,114,43, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,209,0,0,0,174,3,0,0,115,4,0,0,0, + 0,3,6,1,122,19,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,169,2,218,9,95,95,99,108,97,115,115,95, + 95,114,131,0,0,0,169,2,114,118,0,0,0,90,5,111, + 116,104,101,114,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,6,95,95,101,113,95,95,180,3,0,0,115, + 6,0,0,0,0,1,12,1,10,255,122,17,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,169,3,218,4,104,97,115,104,114,116,0,0, + 0,114,43,0,0,0,169,1,114,118,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,8,95,95, + 104,97,115,104,95,95,184,3,0,0,115,2,0,0,0,0, + 1,122,19,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,2,0,0,0,3,0,0,0,3,0,0,0,115, + 16,0,0,0,116,0,116,1,124,0,131,2,160,2,124,1, + 161,1,83,0,41,1,122,100,76,111,97,100,32,97,32,109, + 111,100,117,108,101,32,102,114,111,109,32,97,32,102,105,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,41,3,218,5, + 115,117,112,101,114,114,239,0,0,0,114,220,0,0,0,114, + 219,0,0,0,169,1,114,241,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,220,0,0,0,187,3,0,0,115,2, + 0,0,0,0,10,122,22,70,105,108,101,76,111,97,100,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,2,0,0,0,1,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,169,1,122,58,82,101,116,117,114,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,116,104,101,32,115,111,117,114, + 99,101,32,102,105,108,101,32,97,115,32,102,111,117,110,100, + 32,98,121,32,116,104,101,32,102,105,110,100,101,114,46,114, + 47,0,0,0,114,219,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,179,0,0,0,199,3,0, + 0,115,2,0,0,0,0,3,122,23,70,105,108,101,76,111, + 97,100,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,3,0, + 0,0,8,0,0,0,67,0,0,0,115,126,0,0,0,116, + 0,124,0,116,1,116,2,102,2,131,2,114,70,116,3,160, + 4,116,5,124,1,131,1,161,1,143,24,125,2,124,2,160, + 6,161,0,87,0,2,0,100,1,4,0,4,0,131,3,1, + 0,83,0,49,0,115,58,48,0,1,0,1,0,1,0,89, + 0,1,0,110,52,116,3,160,7,124,1,100,2,161,2,143, + 24,125,2,124,2,160,6,161,0,87,0,2,0,100,1,4, + 0,4,0,131,3,1,0,83,0,49,0,115,112,48,0,1, + 0,1,0,1,0,89,0,1,0,100,1,83,0,41,3,122, + 39,82,101,116,117,114,110,32,116,104,101,32,100,97,116,97, + 32,102,114,111,109,32,112,97,116,104,32,97,115,32,114,97, + 119,32,98,121,116,101,115,46,78,218,1,114,41,8,114,161, + 0,0,0,114,221,0,0,0,218,19,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,114,63,0, + 0,0,90,9,111,112,101,110,95,99,111,100,101,114,84,0, + 0,0,90,4,114,101,97,100,114,64,0,0,0,41,3,114, + 118,0,0,0,114,43,0,0,0,114,67,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,227,0, + 0,0,204,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,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,221,0,0,0,23,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,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,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,116,104,101,32,108,111,97,100,101,114,32,112, - 114,111,116,111,99,111,108,32,109,101,116,104,111,100,115,32, - 116,104,97,116,10,32,32,32,32,114,101,113,117,105,114,101, - 32,102,105,108,101,32,115,121,115,116,101,109,32,117,115,97, - 103,101,46,99,3,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,1,83, - 0,41,2,122,75,67,97,99,104,101,32,116,104,101,32,109, - 111,100,117,108,101,32,110,97,109,101,32,97,110,100,32,116, - 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,102, - 105,108,101,32,102,111,117,110,100,32,98,121,32,116,104,101, - 10,32,32,32,32,32,32,32,32,102,105,110,100,101,114,46, - 78,114,159,0,0,0,41,3,114,118,0,0,0,114,139,0, - 0,0,114,43,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,209,0,0,0,172,3,0,0,115, - 4,0,0,0,0,3,6,1,122,19,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,169,2,218,9,95,95,99,108, - 97,115,115,95,95,114,131,0,0,0,169,2,114,118,0,0, - 0,90,5,111,116,104,101,114,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,6,95,95,101,113,95,95,178, - 3,0,0,115,6,0,0,0,0,1,12,1,10,255,122,17, - 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,169,3,218,4,104,97,115,104, - 114,116,0,0,0,114,43,0,0,0,169,1,114,118,0,0, + 0,218,19,103,101,116,95,114,101,115,111,117,114,99,101,95, + 114,101,97,100,101,114,215,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,72,0,0,0,114,251,0,0,0, + 41,5,114,37,0,0,0,114,46,0,0,0,114,43,0,0, + 0,114,63,0,0,0,114,64,0,0,0,169,3,114,118,0, + 0,0,90,8,114,101,115,111,117,114,99,101,114,43,0,0, 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,8,95,95,104,97,115,104,95,95,182,3,0,0,115,2, - 0,0,0,0,1,122,19,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,2,0,0,0,3,0,0,0,3, - 0,0,0,115,16,0,0,0,116,0,116,1,124,0,131,2, - 160,2,124,1,161,1,83,0,41,1,122,100,76,111,97,100, - 32,97,32,109,111,100,117,108,101,32,102,114,111,109,32,97, - 32,102,105,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, - 41,3,218,5,115,117,112,101,114,114,239,0,0,0,114,220, - 0,0,0,114,219,0,0,0,169,1,114,241,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,220,0,0,0,185,3, - 0,0,115,2,0,0,0,0,10,122,22,70,105,108,101,76, - 111,97,100,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,2,0, - 0,0,1,0,0,0,67,0,0,0,115,6,0,0,0,124, - 0,106,0,83,0,169,1,122,58,82,101,116,117,114,110,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32, - 115,111,117,114,99,101,32,102,105,108,101,32,97,115,32,102, - 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100, - 101,114,46,114,47,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,179,0,0, - 0,197,3,0,0,115,2,0,0,0,0,3,122,23,70,105, - 108,101,76,111,97,100,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,3,0,0,0,10,0,0,0,67,0,0,0,115,102, - 0,0,0,116,0,124,0,116,1,116,2,102,2,131,2,114, - 58,116,3,160,4,116,5,124,1,131,1,161,1,143,22,125, - 2,124,2,160,6,161,0,87,0,2,0,53,0,81,0,82, - 0,163,0,83,0,81,0,82,0,88,0,110,40,116,3,160, - 7,124,1,100,1,161,2,143,22,125,2,124,2,160,6,161, - 0,87,0,2,0,53,0,81,0,82,0,163,0,83,0,81, - 0,82,0,88,0,100,2,83,0,41,3,122,39,82,101,116, - 117,114,110,32,116,104,101,32,100,97,116,97,32,102,114,111, - 109,32,112,97,116,104,32,97,115,32,114,97,119,32,98,121, - 116,101,115,46,218,1,114,78,41,8,114,161,0,0,0,114, - 221,0,0,0,218,19,69,120,116,101,110,115,105,111,110,70, - 105,108,101,76,111,97,100,101,114,114,63,0,0,0,90,9, - 111,112,101,110,95,99,111,100,101,114,84,0,0,0,90,4, - 114,101,97,100,114,64,0,0,0,41,3,114,118,0,0,0, - 114,43,0,0,0,114,67,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,227,0,0,0,202,3, - 0,0,115,10,0,0,0,0,2,14,1,16,1,28,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,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,19,103, - 101,116,95,114,101,115,111,117,114,99,101,95,114,101,97,100, - 101,114,213,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,72,0,0,0,114,251,0,0,0,41,5,114,37, - 0,0,0,114,46,0,0,0,114,43,0,0,0,114,63,0, - 0,0,114,64,0,0,0,169,3,114,118,0,0,0,90,8, - 114,101,115,111,117,114,99,101,114,43,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,13,111,112, - 101,110,95,114,101,115,111,117,114,99,101,219,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,72,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,37,0,0,0,114,46,0,0,0,114,43,0,0,0,114, - 255,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,13,114,101,115,111,117,114,99,101,95,112,97, - 116,104,223,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,107, - 6,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,72,0,0,0,41,5,114,34, - 0,0,0,114,37,0,0,0,114,46,0,0,0,114,43,0, - 0,0,114,53,0,0,0,169,3,114,118,0,0,0,114,116, - 0,0,0,114,43,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,2,1,0,0,229,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,2,0,0,0,218,7,108, - 105,115,116,100,105,114,114,46,0,0,0,114,43,0,0,0, - 114,246,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,8,99,111,110,116,101,110,116,115,235,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, - 3,0,0,0,114,3,0,0,0,114,249,0,0,0,114,6, - 0,0,0,114,239,0,0,0,167,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,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,90,5,100,6, - 100,7,156,1,100,8,100,9,132,2,90,6,100,10,83,0, - 41,11,218,16,83,111,117,114,99,101,70,105,108,101,76,111, - 97,100,101,114,122,62,67,111,110,99,114,101,116,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,83,111,117,114,99,101,76,111,97,100,101,114,32,117,115, - 105,110,103,32,116,104,101,32,102,105,108,101,32,115,121,115, - 116,101,109,46,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,22,0, - 0,0,116,0,124,1,131,1,125,2,124,2,106,1,124,2, - 106,2,100,1,156,2,83,0,41,2,122,33,82,101,116,117, - 114,110,32,116,104,101,32,109,101,116,97,100,97,116,97,32, - 102,111,114,32,116,104,101,32,112,97,116,104,46,41,2,114, - 169,0,0,0,114,234,0,0,0,41,3,114,48,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,43,0,0,0,114, - 238,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,224,0,0,0,243,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,0,0,0,5, - 0,0,0,5,0,0,0,67,0,0,0,115,24,0,0,0, - 116,0,124,1,131,1,125,4,124,0,106,1,124,2,124,3, - 124,4,100,1,141,3,83,0,41,2,78,169,1,218,5,95, - 109,111,100,101,41,2,114,114,0,0,0,114,225,0,0,0, - 41,5,114,118,0,0,0,114,107,0,0,0,114,106,0,0, - 0,114,25,0,0,0,114,51,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,226,0,0,0,248, - 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,59, - 0,0,0,114,11,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,124,4,131,1, - 115,52,116,0,124,4,131,1,92,2,125,4,125,7,124,6, - 160,2,124,7,161,1,1,0,113,16,116,3,124,6,131,1, - 68,0,93,108,125,7,116,4,124,4,124,7,131,2,125,4, - 122,14,116,5,160,6,124,4,161,1,1,0,87,0,113,60, - 4,0,116,7,107,10,114,112,1,0,1,0,1,0,89,0, - 113,60,89,0,113,60,4,0,116,8,107,10,114,166,1,0, - 125,8,1,0,122,26,116,9,160,10,100,1,124,4,124,8, - 161,3,1,0,87,0,89,0,162,6,1,0,100,2,83,0, - 100,2,125,8,126,8,88,0,89,0,113,60,88,0,113,60, - 122,28,116,11,124,1,124,2,124,3,131,3,1,0,116,9, - 160,10,100,3,124,1,161,2,1,0,87,0,110,48,4,0, - 116,8,107,10,114,246,1,0,125,8,1,0,122,18,116,9, - 160,10,100,1,124,1,124,8,161,3,1,0,87,0,53,0, - 100,2,125,8,126,8,88,0,89,0,110,2,88,0,100,2, - 83,0,41,4,122,27,87,114,105,116,101,32,98,121,116,101, - 115,32,100,97,116,97,32,116,111,32,97,32,102,105,108,101, - 46,122,27,99,111,117,108,100,32,110,111,116,32,99,114,101, - 97,116,101,32,123,33,114,125,58,32,123,33,114,125,78,122, - 12,99,114,101,97,116,101,100,32,123,33,114,125,41,12,114, - 46,0,0,0,114,55,0,0,0,114,186,0,0,0,114,41, - 0,0,0,114,37,0,0,0,114,2,0,0,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,49,0,0,0,114,134,0,0,0,114, - 149,0,0,0,114,68,0,0,0,41,9,114,118,0,0,0, - 114,43,0,0,0,114,25,0,0,0,114,12,1,0,0,218, - 6,112,97,114,101,110,116,114,96,0,0,0,114,36,0,0, - 0,114,32,0,0,0,114,228,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,225,0,0,0,253, - 3,0,0,115,48,0,0,0,0,2,12,1,4,2,12,1, - 12,1,12,2,12,1,10,1,2,1,14,1,14,2,8,1, - 16,3,6,1,2,0,2,255,4,2,28,1,2,1,12,1, - 16,1,16,2,8,1,2,255,122,25,83,111,117,114,99,101, - 70,105,108,101,76,111,97,100,101,114,46,115,101,116,95,100, - 97,116,97,78,41,7,114,125,0,0,0,114,124,0,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,3,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,9,1, - 0,0,239,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,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, + 218,13,111,112,101,110,95,114,101,115,111,117,114,99,101,221, + 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,72,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,37,0,0,0,114,46,0,0,0,114,43, + 0,0,0,114,255,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,13,114,101,115,111,117,114,99, + 101,95,112,97,116,104,225,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,107,6,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,72,0,0,0, + 41,5,114,34,0,0,0,114,37,0,0,0,114,46,0,0, + 0,114,43,0,0,0,114,53,0,0,0,169,3,114,118,0, + 0,0,114,116,0,0,0,114,43,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,2,1,0,0, + 231,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,2,0,0, + 0,218,7,108,105,115,116,100,105,114,114,46,0,0,0,114, + 43,0,0,0,114,246,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,8,99,111,110,116,101,110, + 116,115,237,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,3,0,0,0,114,3,0,0,0,114,249,0, + 0,0,114,6,0,0,0,114,239,0,0,0,169,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,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, - 90,5,100,6,83,0,41,7,218,20,83,111,117,114,99,101, - 108,101,115,115,70,105,108,101,76,111,97,100,101,114,122,45, - 76,111,97,100,101,114,32,119,104,105,99,104,32,104,97,110, - 100,108,101,115,32,115,111,117,114,99,101,108,101,115,115,32, - 102,105,108,101,32,105,109,112,111,114,116,115,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0, - 0,0,67,0,0,0,115,68,0,0,0,124,0,160,0,124, - 1,161,1,125,2,124,0,160,1,124,2,161,1,125,3,124, - 1,124,2,100,1,156,2,125,4,116,2,124,3,124,1,124, - 4,131,3,1,0,116,3,116,4,124,3,131,1,100,2,100, - 0,133,2,25,0,124,1,124,2,100,3,141,3,83,0,41, - 4,78,114,159,0,0,0,114,145,0,0,0,41,2,114,116, - 0,0,0,114,106,0,0,0,41,5,114,179,0,0,0,114, - 227,0,0,0,114,152,0,0,0,114,165,0,0,0,114,235, - 0,0,0,41,5,114,118,0,0,0,114,139,0,0,0,114, - 43,0,0,0,114,25,0,0,0,114,151,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,213,0, - 0,0,32,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,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,39,82,101,116,117,114,110,32,78,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,3, - 0,0,0,114,219,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,229,0,0,0,48,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,3,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,15,1, - 0,0,28,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,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,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, - 101,12,100,18,100,19,132,0,131,1,90,13,100,20,83,0, - 41,21,114,252,0,0,0,122,93,76,111,97,100,101,114,32, - 102,111,114,32,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,115,46,10,10,32,32,32,32,84,104,101,32, - 99,111,110,115,116,114,117,99,116,111,114,32,105,115,32,100, - 101,115,105,103,110,101,100,32,116,111,32,119,111,114,107,32, - 119,105,116,104,32,70,105,108,101,70,105,110,100,101,114,46, - 10,10,32,32,32,32,99,3,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,109,0,0,0,114,159,0,0,0,114,5, - 1,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,209,0,0,0,65,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,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,243,0,0,0,69,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,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,247,0,0,0,73,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,43,0,0,0,41,3,114,118,0,0,0,114, - 187,0,0,0,114,216,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,212,0,0,0,76,4,0, - 0,115,18,0,0,0,0,2,4,1,4,0,2,255,4,2, - 6,1,4,0,4,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,43,0,0,0,114,253,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,217,0,0, - 0,84,4,0,0,115,10,0,0,0,0,2,14,1,6,1, - 4,0,4,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,38,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,3,0,0,0,169,2,114,31,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,3,0,0,0,114,6,0,0,0,218,9,60,103, - 101,110,101,120,112,114,62,93,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,46,0,0,0,114,43, - 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,3,0,0,0,114,18,1,0,0,114,6,0,0,0, - 114,182,0,0,0,90,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,3,0,0, - 0,114,219,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,213,0,0,0,96,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, - 3,0,0,0,114,219,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,229,0,0,0,100,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,47,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,179,0,0,0,104, - 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,3,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,252,0,0,0,57,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, + 90,5,100,6,100,7,156,1,100,8,100,9,132,2,90,6, + 100,10,83,0,41,11,218,16,83,111,117,114,99,101,70,105, + 108,101,76,111,97,100,101,114,122,62,67,111,110,99,114,101, + 116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,32,111,102,32,83,111,117,114,99,101,76,111,97,100,101, + 114,32,117,115,105,110,103,32,116,104,101,32,102,105,108,101, + 32,115,121,115,116,101,109,46,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,22,0,0,0,116,0,124,1,131,1,125,2,124,2, + 106,1,124,2,106,2,100,1,156,2,83,0,41,2,122,33, + 82,101,116,117,114,110,32,116,104,101,32,109,101,116,97,100, + 97,116,97,32,102,111,114,32,116,104,101,32,112,97,116,104, + 46,41,2,114,169,0,0,0,114,234,0,0,0,41,3,114, + 48,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,43, + 0,0,0,114,238,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,224,0,0,0,245,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, + 0,0,0,5,0,0,0,5,0,0,0,67,0,0,0,115, + 24,0,0,0,116,0,124,1,131,1,125,4,124,0,106,1, + 124,2,124,3,124,4,100,1,141,3,83,0,41,2,78,169, + 1,218,5,95,109,111,100,101,41,2,114,114,0,0,0,114, + 225,0,0,0,41,5,114,118,0,0,0,114,107,0,0,0, + 114,106,0,0,0,114,25,0,0,0,114,51,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,226, + 0,0,0,250,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,59,0,0,0,114,11,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,2,1,0,0,116,0,124,1,131,1, + 92,2,125,4,125,5,103,0,125,6,124,4,114,52,116,1, + 124,4,131,1,115,52,116,0,124,4,131,1,92,2,125,4, + 125,7,124,6,160,2,124,7,161,1,1,0,113,16,116,3, + 124,6,131,1,68,0,93,108,125,7,116,4,124,4,124,7, + 131,2,125,4,122,14,116,5,160,6,124,4,161,1,1,0, + 87,0,113,60,4,0,116,7,107,10,114,112,1,0,1,0, + 1,0,89,0,113,60,89,0,113,60,4,0,116,8,107,10, + 114,166,1,0,125,8,1,0,122,30,116,9,160,10,100,1, + 124,4,124,8,161,3,1,0,87,0,89,0,100,2,125,8, + 126,8,1,0,100,2,83,0,100,2,125,8,126,8,48,0, + 48,0,113,60,122,28,116,11,124,1,124,2,124,3,131,3, + 1,0,116,9,160,10,100,3,124,1,161,2,1,0,87,0, + 110,54,4,0,116,8,107,10,144,0,114,252,1,0,125,8, + 1,0,122,26,116,9,160,10,100,1,124,1,124,8,161,3, + 1,0,87,0,89,0,100,2,125,8,126,8,110,10,100,2, + 125,8,126,8,48,0,48,0,100,2,83,0,41,4,122,27, + 87,114,105,116,101,32,98,121,116,101,115,32,100,97,116,97, + 32,116,111,32,97,32,102,105,108,101,46,122,27,99,111,117, + 108,100,32,110,111,116,32,99,114,101,97,116,101,32,123,33, + 114,125,58,32,123,33,114,125,78,122,12,99,114,101,97,116, + 101,100,32,123,33,114,125,41,12,114,46,0,0,0,114,55, + 0,0,0,114,186,0,0,0,114,41,0,0,0,114,37,0, + 0,0,114,2,0,0,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, + 49,0,0,0,114,134,0,0,0,114,149,0,0,0,114,68, + 0,0,0,41,9,114,118,0,0,0,114,43,0,0,0,114, + 25,0,0,0,114,12,1,0,0,218,6,112,97,114,101,110, + 116,114,96,0,0,0,114,36,0,0,0,114,32,0,0,0, + 114,228,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,225,0,0,0,255,3,0,0,115,48,0, + 0,0,0,2,12,1,4,2,12,1,12,1,12,2,12,1, + 10,1,2,1,14,1,14,2,8,1,16,3,6,1,2,0, + 2,255,4,2,28,1,2,1,12,1,16,1,18,2,8,1, + 2,255,122,25,83,111,117,114,99,101,70,105,108,101,76,111, + 97,100,101,114,46,115,101,116,95,100,97,116,97,78,41,7, + 114,125,0,0,0,114,124,0,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,3,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,9,1,0,0,241,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,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,64,0,0,0,115,104,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,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,43,0,0,0,90,11,112,97,116,104,95,102,105,110,100, - 101,114,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,209,0,0,0,117,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,70,0,0,0,114,39,0,0,0, - 41,2,114,8,0,0,0,114,43,0,0,0,90,8,95,95, - 112,97,116,104,95,95,41,2,114,23,1,0,0,114,40,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,3,0,0,0,114,3,0,0, - 0,114,6,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,123, - 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,8,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,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,25,1,0,0, - 133,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,107,9,114,68,124,2,106,5,100,0,107,8, - 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,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,12,95,114,101,99,97,108,99,117,108,97,116, - 101,137,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,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,8,95,95,105,116,101,114,95,95, - 150,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,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,95,95,103,101,116,105,116, - 101,109,95,95,153,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,24, - 1,0,0,41,3,114,118,0,0,0,114,35,1,0,0,114, - 43,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,11,95,95,115,101,116,105,116,101,109,95,95, - 156,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,22,0,0,0,114,32,1, - 0,0,114,246,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,7,95,95,108,101,110,95,95,159, - 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,61,0,0,0,114,24,1,0, - 0,114,246,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,8,95,95,114,101,112,114,95,95,162, - 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,107,6,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,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,12,95,95,99,111,110,116,97,105,110,115,95, - 95,165,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,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,186,0,0, - 0,168,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,3,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,22,1,0,0,110,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,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,209,0,0,0,174,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,61,0,0,0,114,125,0,0,0,41,2,114,193,0,0, - 0,114,216,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,11,109,111,100,117,108,101,95,114,101, - 112,114,177,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,3,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,182,0,0,0,186, - 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,39,0,0, - 0,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,189, - 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,39,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 213,0,0,0,192,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, + 132,0,90,4,100,4,100,5,132,0,90,5,100,6,83,0, + 41,7,218,20,83,111,117,114,99,101,108,101,115,115,70,105, + 108,101,76,111,97,100,101,114,122,45,76,111,97,100,101,114, + 32,119,104,105,99,104,32,104,97,110,100,108,101,115,32,115, + 111,117,114,99,101,108,101,115,115,32,102,105,108,101,32,105, + 109,112,111,114,116,115,46,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, + 115,68,0,0,0,124,0,160,0,124,1,161,1,125,2,124, + 0,160,1,124,2,161,1,125,3,124,1,124,2,100,1,156, + 2,125,4,116,2,124,3,124,1,124,4,131,3,1,0,116, + 3,116,4,124,3,131,1,100,2,100,0,133,2,25,0,124, + 1,124,2,100,3,141,3,83,0,41,4,78,114,159,0,0, + 0,114,145,0,0,0,41,2,114,116,0,0,0,114,106,0, + 0,0,41,5,114,179,0,0,0,114,227,0,0,0,114,152, + 0,0,0,114,165,0,0,0,114,235,0,0,0,41,5,114, + 118,0,0,0,114,139,0,0,0,114,43,0,0,0,114,25, + 0,0,0,114,151,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,213,0,0,0,34,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,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,3,0,0,0,114,211,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,212,0,0,0,195, - 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,3,0,0,0,114,253,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,217,0,0,0,198, - 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,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,220,0,0,0,201,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,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 43,1,0,0,173,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,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,107,8, - 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,8,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, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,39, + 82,101,116,117,114,110,32,78,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,3,0,0,0,114,219,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,229,0,0,0,50,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,3,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,15,1,0,0,30,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,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,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,101,12,100,18,100,19, + 132,0,131,1,90,13,100,20,83,0,41,21,114,252,0,0, + 0,122,93,76,111,97,100,101,114,32,102,111,114,32,101,120, + 116,101,110,115,105,111,110,32,109,111,100,117,108,101,115,46, + 10,10,32,32,32,32,84,104,101,32,99,111,110,115,116,114, + 117,99,116,111,114,32,105,115,32,100,101,115,105,103,110,101, + 100,32,116,111,32,119,111,114,107,32,119,105,116,104,32,70, + 105,108,101,70,105,110,100,101,114,46,10,10,32,32,32,32, + 99,3,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,109, + 0,0,0,114,159,0,0,0,114,5,1,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,209,0,0, + 0,67,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,243,0,0,0,71,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,247,0,0,0,75,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,43,0, + 0,0,41,3,114,118,0,0,0,114,187,0,0,0,114,216, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,212,0,0,0,78,4,0,0,115,18,0,0,0, + 0,2,4,1,4,0,2,255,4,2,6,1,4,0,4,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,43,0, + 0,0,114,253,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,217,0,0,0,86,4,0,0,115, + 10,0,0,0,0,2,14,1,6,1,4,0,4,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,38,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,3,0,0,0, + 169,2,114,31,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,3,0,0, + 0,114,6,0,0,0,218,9,60,103,101,110,101,120,112,114, + 62,95,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,46,0,0,0,114,43,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,3,0,0,0, + 114,18,1,0,0,114,6,0,0,0,114,182,0,0,0,92, + 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,3,0,0,0,114,219,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 46,1,0,0,219,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,84, - 0,0,0,116,0,106,1,100,1,107,9,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,44,125,2,122,14,124,2,124,1,131, - 1,87,0,2,0,1,0,83,0,4,0,116,5,107,10,114, - 76,1,0,1,0,1,0,89,0,113,34,89,0,113,34,88, - 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,8,0,0,0,218,10,112,97,116,104, - 95,104,111,111,107,115,114,74,0,0,0,114,75,0,0,0, - 114,138,0,0,0,114,117,0,0,0,41,3,114,193,0,0, - 0,114,43,0,0,0,90,4,104,111,111,107,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,11,95,112,97, - 116,104,95,104,111,111,107,115,229,4,0,0,115,16,0,0, - 0,0,3,16,1,12,1,10,1,2,1,14,1,14,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,104,0,0,0,124,1,100,1,107,2,114,44,122, - 12,116,0,160,1,161,0,125,1,87,0,110,22,4,0,116, - 2,107,10,114,42,1,0,1,0,1,0,89,0,100,2,83, - 0,88,0,122,14,116,3,106,4,124,1,25,0,125,2,87, - 0,110,40,4,0,116,5,107,10,114,98,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,88,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,39,0,0,0,78,41,7,114,2,0, - 0,0,114,54,0,0,0,114,3,1,0,0,114,8,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,43,0,0, - 0,114,50,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,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,242,4,0,0,115, - 22,0,0,0,0,8,8,1,2,1,12,1,14,3,8,1, - 2,1,14,1,14,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,107,9,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,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,16,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,8,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,107,9,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,107,8,114,92,113,8,124,7,106,7, - 100,1,107,9,114,110,124,7,2,0,1,0,83,0,124,7, - 106,8,125,8,124,8,100,1,107,8,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,43,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,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,9,95,103,101,116,95,115,112,101,99,23, - 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,107,8,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,107,8,114,40,100,1,83,0,124,4,106,3, - 100,1,107,8,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,32,32,32,32,32,32,32,32,78,41,7,114,8,0,0, - 0,114,43,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,43,0,0,0, - 114,202,0,0,0,114,187,0,0,0,114,57,1,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,203, - 0,0,0,55,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,107,8,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, + 213,0,0,0,98,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,3,0,0,0,114,219, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,229,0,0,0,102,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,47,0,0,0, + 114,219,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,179,0,0,0,106,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, + 3,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,252,0,0,0,59,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,43,0,0,0,90, + 11,112,97,116,104,95,102,105,110,100,101,114,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,209,0,0,0, + 119,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,70,0,0,0,114,39,0,0,0,41,2,114,8,0,0, + 0,114,43,0,0,0,90,8,95,95,112,97,116,104,95,95, + 41,2,114,23,1,0,0,114,40,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,3,0,0,0,114,3,0,0,0,114,6,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,125,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,8,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,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,25,1,0,0,135,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,107,9, + 114,68,124,2,106,5,100,0,107,8,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,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,12,95, + 114,101,99,97,108,99,117,108,97,116,101,139,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,206,0,0,0,79,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,3, - 0,0,0,79,0,0,0,115,24,0,0,0,100,1,100,2, - 108,0,109,1,125,3,1,0,124,3,106,2,124,1,124,2, - 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,72,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,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,60,1,0,0,92, - 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,3,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,45,1,0, - 0,215,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,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,3, - 0,0,0,114,16,1,0,0,169,1,114,140,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,19,1,0,0,121,5, - 0,0,115,4,0,0,0,4,0,2,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,70,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, - 43,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, - 43,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,3,0,0,0,114,62,1,0,0,114,6,0,0, - 0,114,209,0,0,0,115,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,64,1,0,0,114,246,0,0, + 218,8,95,95,105,116,101,114,95,95,152,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,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,11,95,95,103,101,116,105,116,101,109,95,95,155,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,24,1,0,0,41,3,114, + 118,0,0,0,114,35,1,0,0,114,43,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,11,95, + 95,115,101,116,105,116,101,109,95,95,158,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,22,0,0,0,114,32,1,0,0,114,246,0,0, 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,46,1,0,0,129,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,107,8,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, + 218,7,95,95,108,101,110,95,95,161,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,61,0,0,0,114,24,1,0,0,114,246,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 8,95,95,114,101,112,114,95,95,164,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,107,6,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,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,12,95, + 95,99,111,110,116,97,105,110,115,95,95,167,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,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,186,0,0,0,170,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,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 22,1,0,0,112,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,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,137,0,0,0,135,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,43,0,0,0,90,4,115,109, - 115,108,114,202,0,0,0,114,140,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,58,1,0,0, - 147,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,98,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,24,4,0,116,6,107,10,114,66,1,0,1,0,1,0, - 100,4,125,5,89,0,110,2,88,0,124,5,124,0,106,7, - 107,3,114,92,124,0,160,8,161,0,1,0,124,5,124,0, - 95,7,116,9,131,0,114,114,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,107,6,114,218,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,150,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,150,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,107,6,114,224,116,15,124,12,131,1, - 114,224,124,0,160,16,124,10,124,1,124,12,100,8,124,2, - 161,5,2,0,1,0,83,0,113,224,124,3,144,1,114,94, - 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,70,0,0, - 0,114,27,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,40,0,0,0,114,48,0,0,0, - 114,43,0,0,0,114,2,0,0,0,114,54,0,0,0,114, - 10,1,0,0,114,49,0,0,0,114,64,1,0,0,218,11, - 95,102,105,108,108,95,99,97,99,104,101,114,7,0,0,0, - 114,67,1,0,0,114,105,0,0,0,114,66,1,0,0,114, - 37,0,0,0,114,63,1,0,0,114,53,0,0,0,114,58, - 1,0,0,114,55,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,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,203,0,0,0,152,5,0,0,115,74, - 0,0,0,0,5,4,1,14,1,2,1,24,1,14,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,2,0,2, - 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,190,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,30,4, - 0,116,4,116,5,116,6,102,3,107,10,114,58,1,0,1, - 0,1,0,103,0,125,2,89,0,110,2,88,0,116,7,106, - 8,160,9,100,1,161,1,115,84,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,136,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,94,124,3,124,0,95,11,116, - 7,106,8,160,9,116,16,161,1,114,186,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,70,0,0, - 0,114,60,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,3,0,0,0,41,1,114, - 105,0,0,0,41,2,114,31,0,0,0,90,2,102,110,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,9, - 60,115,101,116,99,111,109,112,62,229,5,0,0,115,4,0, - 0,0,6,0,2,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,43,0,0,0,114,2,0,0,0,114,7, - 1,0,0,114,54,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,8,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,65,1,0,0,114,66,1,0,0,114,100,0,0,0, - 114,61,0,0,0,114,105,0,0,0,218,3,97,100,100,114, - 11,0,0,0,114,67,1,0,0,41,9,114,118,0,0,0, - 114,43,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, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,69, - 1,0,0,200,5,0,0,115,34,0,0,0,0,2,6,1, - 2,1,22,1,20,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,34,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,102,1,136,1,158,2,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,47,0,0,0,41,2,114,55,0,0,0,114,117, - 0,0,0,114,47,0,0,0,169,2,114,193,0,0,0,114, - 68,1,0,0,114,3,0,0,0,114,6,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,241,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, - 3,0,0,0,41,3,114,193,0,0,0,114,68,1,0,0, - 114,75,1,0,0,114,3,0,0,0,114,74,1,0,0,114, - 6,0,0,0,218,9,112,97,116,104,95,104,111,111,107,231, - 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,61,0,0,0,114,43,0,0,0,114,246,0, + 0,114,209,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,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,61,0,0,0,114, + 125,0,0,0,41,2,114,193,0,0,0,114,216,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 11,109,111,100,117,108,101,95,114,101,112,114,179,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,3,0,0,0, + 114,219,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,182,0,0,0,188,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,39,0,0,0,114,3,0,0,0, + 114,219,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,229,0,0,0,191,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,39,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,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,213,0,0,0,194,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,3,0,0,0, + 114,211,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,212,0,0,0,197,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,3,0,0,0, + 114,253,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,217,0,0,0,200,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,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,220,0,0,0,203,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,3,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,43,1,0,0,175,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,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,107,8,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,8,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,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,46,1,0,0,221,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,84,0,0,0,116,0,106, + 1,100,1,107,9,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, + 44,125,2,122,14,124,2,124,1,131,1,87,0,2,0,1, + 0,83,0,4,0,116,5,107,10,114,76,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, + 8,0,0,0,218,10,112,97,116,104,95,104,111,111,107,115, + 114,74,0,0,0,114,75,0,0,0,114,138,0,0,0,114, + 117,0,0,0,41,3,114,193,0,0,0,114,43,0,0,0, + 90,4,104,111,111,107,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,11,95,112,97,116,104,95,104,111,111, + 107,115,231,4,0,0,115,16,0,0,0,0,3,16,1,12, + 1,10,1,2,1,14,1,14,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,104,0,0, + 0,124,1,100,1,107,2,114,44,122,12,116,0,160,1,161, + 0,125,1,87,0,110,22,4,0,116,2,107,10,114,42,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,40,4,0,116, + 5,107,10,114,98,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, + 39,0,0,0,78,41,7,114,2,0,0,0,114,54,0,0, + 0,114,3,1,0,0,114,8,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,43,0,0,0,114,50,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,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,244,4,0,0,115,22,0,0,0,0,8, + 8,1,2,1,12,1,14,3,8,1,2,1,14,1,14,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,107, + 9,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,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,39,1,0,0,249,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,69,1,0,0,114,207,0,0,0,114,76,1,0, - 0,114,39,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,61,1,0,0,106, - 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,146,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,20,4,0,116,5,107, - 10,114,140,1,0,1,0,1,0,89,0,110,2,88,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,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,14,95,102,105,120,95,117,112,95, - 109,111,100,117,108,101,255,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,14, - 2,114,81,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,184,0,0,0,22,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,12,0,0,0,9,0,0,0, - 67,0,0,0,115,178,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,68,0,93,48,125,2,124,2,116,1,106, - 3,107,7,114,56,116,0,160,5,124,2,161,1,125,3,110, - 10,116,1,106,3,124,2,25,0,125,3,116,6,124,1,124, - 2,124,3,131,3,1,0,113,30,100,2,100,3,103,1,102, - 2,100,4,100,5,100,3,103,2,102,2,102,2,125,4,124, - 4,68,0,93,110,92,2,125,5,125,6,116,7,100,6,100, - 7,132,0,124,6,68,0,131,1,131,1,115,136,74,0,130, - 1,124,6,100,8,25,0,125,7,124,5,116,1,106,3,107, - 6,114,170,116,1,106,3,124,5,25,0,125,8,1,0,113, - 226,113,106,122,20,116,0,160,5,124,5,161,1,125,8,87, - 0,1,0,113,226,87,0,113,106,4,0,116,8,107,10,114, - 214,1,0,1,0,1,0,89,0,113,106,89,0,113,106,88, - 0,113,106,116,8,100,9,131,1,130,1,116,6,124,1,100, - 10,124,8,131,3,1,0,116,6,124,1,100,11,124,7,131, - 3,1,0,116,6,124,1,100,12,100,13,160,9,124,6,161, - 1,131,3,1,0,116,6,124,1,100,14,100,15,100,16,132, - 0,124,6,68,0,131,1,131,3,1,0,116,0,160,5,100, - 17,161,1,125,9,116,6,124,1,100,17,124,9,131,3,1, - 0,116,0,160,5,100,18,161,1,125,10,116,6,124,1,100, - 18,124,10,131,3,1,0,124,5,100,4,107,2,144,1,114, - 110,116,0,160,5,100,19,161,1,125,11,116,6,124,1,100, - 20,124,11,131,3,1,0,116,6,124,1,100,21,116,10,131, - 0,131,3,1,0,116,11,160,12,116,2,160,13,161,0,161, - 1,1,0,124,5,100,4,107,2,144,1,114,174,116,14,160, - 15,100,22,161,1,1,0,100,23,116,11,107,6,144,1,114, - 174,100,24,116,16,95,17,100,25,83,0,41,26,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,41,4,114,63, - 0,0,0,114,74,0,0,0,218,8,98,117,105,108,116,105, - 110,115,114,160,0,0,0,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,38,0,0,0,78,41,1,114,22,0,0,0,41, - 2,114,31,0,0,0,114,94,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,19,1,0,0,58, - 6,0,0,115,4,0,0,0,4,0,2,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,72,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,2,0,0, - 0,114,34,0,0,0,114,30,0,0,0,114,39,0,0,0, - 114,57,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,73,0,0,0, - 114,3,0,0,0,41,2,114,31,0,0,0,218,1,115,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,70, - 1,0,0,74,6,0,0,115,4,0,0,0,6,0,2,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,90,7,95,116,104, - 114,101,97,100,90,8,95,119,101,97,107,114,101,102,90,6, - 119,105,110,114,101,103,114,192,0,0,0,114,7,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,8,0,0,0,114,163,0,0, - 0,114,31,1,0,0,114,125,0,0,0,90,18,95,98,117, - 105,108,116,105,110,95,102,114,111,109,95,110,97,109,101,114, - 129,0,0,0,218,3,97,108,108,114,117,0,0,0,114,35, - 0,0,0,114,13,0,0,0,114,21,1,0,0,114,167,0, - 0,0,114,82,1,0,0,114,101,0,0,0,114,186,0,0, - 0,114,191,0,0,0,114,195,0,0,0,41,12,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,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,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,30,0,0,0,114,34,0,0,0,90,9,111, - 115,95,109,111,100,117,108,101,90,13,116,104,114,101,97,100, - 95,109,111,100,117,108,101,90,14,119,101,97,107,114,101,102, - 95,109,111,100,117,108,101,90,13,119,105,110,114,101,103,95, - 109,111,100,117,108,101,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,6,95,115,101,116,117,112,33,6,0, - 0,115,78,0,0,0,0,8,4,1,6,1,6,3,10,1, - 8,1,10,1,12,2,10,1,14,3,22,1,12,2,22,1, - 8,1,10,1,10,1,6,2,2,1,10,1,10,1,14,1, - 12,2,8,1,12,1,12,1,18,1,22,3,10,1,12,3, - 10,1,12,3,10,1,10,1,12,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,8,0,0,0,114,51,1,0,0,114,167,0, - 0,0,114,61,1,0,0,114,76,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,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,8,95,105,110,115, - 116,97,108,108,98,6,0,0,115,8,0,0,0,0,2,8, - 1,6,1,20,1,114,91,1,0,0,41,1,114,59,0,0, - 0,41,1,78,41,3,78,78,78,41,2,114,72,0,0,0, - 114,72,0,0,0,41,1,84,41,1,78,41,1,78,41,63, - 114,127,0,0,0,114,12,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,11,0,0,0,114,13,0,0,0,114,20,0,0,0, - 114,26,0,0,0,114,28,0,0,0,114,37,0,0,0,114, - 46,0,0,0,114,48,0,0,0,114,52,0,0,0,114,53, - 0,0,0,114,55,0,0,0,114,58,0,0,0,114,68,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,18,0,0,0,114,148,0,0, - 0,114,17,0,0,0,114,23,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,81, - 1,0,0,114,184,0,0,0,114,89,1,0,0,114,91,1, + 0,218,16,95,108,101,103,97,99,121,95,103,101,116,95,115, + 112,101,99,10,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,107,9,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, + 107,8,114,92,113,8,124,7,106,7,100,1,107,9,114,110, + 124,7,2,0,1,0,83,0,124,7,106,8,125,8,124,8, + 100,1,107,8,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, + 43,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, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,9, + 95,103,101,116,95,115,112,101,99,25,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,107,8,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,107,8, + 114,40,100,1,83,0,124,4,106,3,100,1,107,8,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,32,32,32,32,32, + 32,32,32,78,41,7,114,8,0,0,0,114,43,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,43,0,0,0,114,202,0,0,0,114, + 187,0,0,0,114,57,1,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,203,0,0,0,57,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,107,8,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,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,206,0,0,0,81, + 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,3,0,0,0,79,0,0, + 0,115,24,0,0,0,100,1,100,2,108,0,109,1,125,3, + 1,0,124,3,106,2,124,1,124,2,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,72,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,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,60,1,0,0,94,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,3,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,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, - 14,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,65, + 0,114,6,0,0,0,114,45,1,0,0,217,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, + 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,3,0,0,0,114,16,1, + 0,0,169,1,114,140,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,19,1,0,0,123,5,0,0,115,4,0,0, + 0,4,0,2,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,70,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,43,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,43,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,3,0,0, + 0,114,62,1,0,0,114,6,0,0,0,114,209,0,0,0, + 117,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,64,1,0,0,114,246,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,46,1,0,0,131, + 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,107,8,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,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,137,0,0,0, + 137,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,43,0,0,0,90,4,115,109,115,108,114,202,0,0, + 0,114,140,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,58,1,0,0,149,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,98,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,24,4,0,116,6, + 107,10,114,66,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,92,124,0, + 160,8,161,0,1,0,124,5,124,0,95,7,116,9,131,0, + 114,114,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, + 107,6,114,218,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,150,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,150,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, + 107,6,114,224,116,15,124,12,131,1,114,224,124,0,160,16, + 124,10,124,1,124,12,100,8,124,2,161,5,2,0,1,0, + 83,0,113,224,124,3,144,1,114,94,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,70,0,0,0,114,27,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,40,0,0,0,114,48,0,0,0,114,43,0,0,0,114, + 2,0,0,0,114,54,0,0,0,114,10,1,0,0,114,49, + 0,0,0,114,64,1,0,0,218,11,95,102,105,108,108,95, + 99,97,99,104,101,114,7,0,0,0,114,67,1,0,0,114, + 105,0,0,0,114,66,1,0,0,114,37,0,0,0,114,63, + 1,0,0,114,53,0,0,0,114,58,1,0,0,114,55,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 203,0,0,0,154,5,0,0,115,74,0,0,0,0,5,4, + 1,14,1,2,1,24,1,14,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,2,0,2,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,190,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,30,4,0,116,4,116,5,116, + 6,102,3,107,10,114,58,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,84,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, + 136,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,94,124,3,124,0,95,11,116,7,106,8,160,9,116, + 16,161,1,114,186,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,70,0,0,0,114,60,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,3,0,0,0,41,1,114,105,0,0,0,41,2, + 114,31,0,0,0,90,2,102,110,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,9,60,115,101,116,99,111, + 109,112,62,231,5,0,0,115,4,0,0,0,6,0,2,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,43, + 0,0,0,114,2,0,0,0,114,7,1,0,0,114,54,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,8,0,0, + 0,114,9,0,0,0,114,10,0,0,0,114,65,1,0,0, + 114,66,1,0,0,114,100,0,0,0,114,61,0,0,0,114, + 105,0,0,0,218,3,97,100,100,114,11,0,0,0,114,67, + 1,0,0,41,9,114,118,0,0,0,114,43,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,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,69,1,0,0,202,5,0, + 0,115,34,0,0,0,0,2,6,1,2,1,22,1,20,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,34,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,102,1,136,1,158,2,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,47,0,0, + 0,41,2,114,55,0,0,0,114,117,0,0,0,114,47,0, + 0,0,169,2,114,193,0,0,0,114,68,1,0,0,114,3, + 0,0,0,114,6,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,243,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,3,0,0,0,41,3, + 114,193,0,0,0,114,68,1,0,0,114,75,1,0,0,114, + 3,0,0,0,114,74,1,0,0,114,6,0,0,0,218,9, + 112,97,116,104,95,104,111,111,107,233,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,61,0, + 0,0,114,43,0,0,0,114,246,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,39,1,0,0, + 251,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,69,1,0, + 0,114,207,0,0,0,114,76,1,0,0,114,39,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,61,1,0,0,108,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,146,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,20,4,0,116,5,107,10,114,140,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,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101, + 1,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,14,2,114,81,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,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,184,0,0,0,24, + 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,12,0,0,0,9,0,0,0,67,0,0,0,115,178, + 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,68, + 0,93,48,125,2,124,2,116,1,106,3,107,7,114,56,116, + 0,160,5,124,2,161,1,125,3,110,10,116,1,106,3,124, + 2,25,0,125,3,116,6,124,1,124,2,124,3,131,3,1, + 0,113,30,100,2,100,3,103,1,102,2,100,4,100,5,100, + 3,103,2,102,2,102,2,125,4,124,4,68,0,93,110,92, + 2,125,5,125,6,116,7,100,6,100,7,132,0,124,6,68, + 0,131,1,131,1,115,136,74,0,130,1,124,6,100,8,25, + 0,125,7,124,5,116,1,106,3,107,6,114,170,116,1,106, + 3,124,5,25,0,125,8,1,0,113,226,113,106,122,20,116, + 0,160,5,124,5,161,1,125,8,87,0,1,0,113,226,87, + 0,113,106,4,0,116,8,107,10,114,214,1,0,1,0,1, + 0,89,0,113,106,89,0,113,106,48,0,113,106,116,8,100, + 9,131,1,130,1,116,6,124,1,100,10,124,8,131,3,1, + 0,116,6,124,1,100,11,124,7,131,3,1,0,116,6,124, + 1,100,12,100,13,160,9,124,6,161,1,131,3,1,0,116, + 6,124,1,100,14,100,15,100,16,132,0,124,6,68,0,131, + 1,131,3,1,0,116,0,160,5,100,17,161,1,125,9,116, + 6,124,1,100,17,124,9,131,3,1,0,116,0,160,5,100, + 18,161,1,125,10,116,6,124,1,100,18,124,10,131,3,1, + 0,124,5,100,4,107,2,144,1,114,110,116,0,160,5,100, + 19,161,1,125,11,116,6,124,1,100,20,124,11,131,3,1, + 0,116,6,124,1,100,21,116,10,131,0,131,3,1,0,116, + 11,160,12,116,2,160,13,161,0,161,1,1,0,124,5,100, + 4,107,2,144,1,114,174,116,14,160,15,100,22,161,1,1, + 0,100,23,116,11,107,6,144,1,114,174,100,24,116,16,95, + 17,100,25,83,0,41,26,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,41,4,114,63,0,0,0,114,74,0, + 0,0,218,8,98,117,105,108,116,105,110,115,114,160,0,0, + 0,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,38,0,0, + 0,78,41,1,114,22,0,0,0,41,2,114,31,0,0,0, + 114,94,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,19,1,0,0,60,6,0,0,115,4,0, + 0,0,4,0,2,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,72,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,2,0,0,0,114,34,0,0,0, + 114,30,0,0,0,114,39,0,0,0,114,57,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,73,0,0,0,114,3,0,0,0,41, + 2,114,31,0,0,0,218,1,115,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,70,1,0,0,76,6,0, + 0,115,4,0,0,0,6,0,2,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,90,7,95,116,104,114,101,97,100,90,8, + 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, + 114,192,0,0,0,114,7,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,8,0,0,0,114,163,0,0,0,114,31,1,0,0, + 114,125,0,0,0,90,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,114,129,0,0,0,218,3, + 97,108,108,114,117,0,0,0,114,35,0,0,0,114,13,0, + 0,0,114,21,1,0,0,114,167,0,0,0,114,82,1,0, + 0,114,101,0,0,0,114,186,0,0,0,114,191,0,0,0, + 114,195,0,0,0,41,12,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,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,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,30,0, + 0,0,114,34,0,0,0,90,9,111,115,95,109,111,100,117, + 108,101,90,13,116,104,114,101,97,100,95,109,111,100,117,108, + 101,90,14,119,101,97,107,114,101,102,95,109,111,100,117,108, + 101,90,13,119,105,110,114,101,103,95,109,111,100,117,108,101, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 6,95,115,101,116,117,112,35,6,0,0,115,78,0,0,0, + 0,8,4,1,6,1,6,3,10,1,8,1,10,1,12,2, + 10,1,14,3,22,1,12,2,22,1,8,1,10,1,10,1, + 6,2,2,1,10,1,10,1,14,1,12,2,8,1,12,1, + 12,1,18,1,22,3,10,1,12,3,10,1,12,3,10,1, + 10,1,12,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,8,0, + 0,0,114,51,1,0,0,114,167,0,0,0,114,61,1,0, + 0,114,76,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,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,8,95,105,110,115,116,97,108,108,100,6, + 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, + 91,1,0,0,41,1,114,59,0,0,0,41,1,78,41,3, + 78,78,78,41,2,114,72,0,0,0,114,72,0,0,0,41, + 1,84,41,1,78,41,1,78,41,63,114,127,0,0,0,114, + 12,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,11,0,0,0, + 114,13,0,0,0,114,20,0,0,0,114,26,0,0,0,114, + 28,0,0,0,114,37,0,0,0,114,46,0,0,0,114,48, + 0,0,0,114,52,0,0,0,114,53,0,0,0,114,55,0, + 0,0,114,58,0,0,0,114,68,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,18,0,0,0,114,148,0,0,0,114,17,0,0,0, + 114,23,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,81,1,0,0,114,184,0, + 0,0,114,89,1,0,0,114,91,1,0,0,114,3,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,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,16,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, + 65, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index 2d10c8c9cf903..21633acb9376a 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -127,12 +127,12 @@ const unsigned char _Py_M__zipimport[] = { 0,116,8,160,12,124,1,161,1,92,2,125,5,125,6,124, 5,124,1,107,2,114,132,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,88,0,124,4,106,14,100,5,64,0,100, + 0,89,0,113,64,48,0,124,4,106,14,100,5,64,0,100, 6,107,3,114,182,116,4,100,4,124,1,100,3,141,2,130, 1,113,182,113,64,122,12,116,15,124,1,25,0,125,7,87, 0,110,36,4,0,116,16,107,10,114,230,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,88,0,124,7,124,0,95,18,124,1,124, + 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, 32,124,0,4,0,106,21,116,7,55,0,2,0,95,21,100, @@ -277,7 +277,7 @@ const unsigned char _Py_M__zipimport[] = { 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,32,4,0,116, 7,107,10,114,104,1,0,1,0,1,0,116,8,100,2,100, - 3,124,2,131,3,130,1,89,0,110,2,88,0,116,9,124, + 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, @@ -323,7 +323,7 @@ const unsigned char _Py_M__zipimport[] = { 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,22,4,0,116,6,107,10,114,110,1,0,1,0,1, - 0,89,0,100,1,83,0,88,0,116,7,124,0,106,8,124, + 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, @@ -389,10 +389,10 @@ const unsigned char _Py_M__zipimport[] = { 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,88,0,122,14,116,1,106,2, + 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,36,4,0,116,17,107,10, 114,228,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,88,0,116,19, + 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, @@ -440,7 +440,7 @@ const unsigned char _Py_M__zipimport[] = { 0,8,0,0,0,67,0,0,0,115,88,0,0,0,122,20, 124,0,160,0,124,1,161,1,115,18,87,0,100,1,83,0, 87,0,110,22,4,0,116,1,107,10,114,42,1,0,1,0, - 1,0,89,0,100,1,83,0,88,0,116,2,106,3,115,78, + 1,0,89,0,100,1,83,0,48,0,116,2,106,3,115,78, 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, @@ -522,28 +522,28 @@ const unsigned char _Py_M__zipimport[] = { 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,252,4,0,0, + 0,0,0,9,0,0,0,67,0,0,0,115,18,5,0,0, 122,14,116,0,160,1,124,0,161,1,125,1,87,0,110,38, 4,0,116,2,107,10,114,52,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,88,0,124,1,144,4,143,168,1,0,122,36, + 89,0,110,2,48,0,124,1,144,4,143,178,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,38,4,0,116,2,107,10,114,136,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,88,0,116,8,124,3,131,1, + 141,2,130,1,89,0,110,2,48,0,116,8,124,3,131,1, 116,5,107,3,114,168,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,178,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,38,4,0,116,2,107,10,114,248,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,88,0,116,10,124,4,116,11, + 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,40,4,0,116,2,107,10,144,1,114,74,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,88,0,124,6,160,12, + 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,114, 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, @@ -562,7 +562,7 @@ const unsigned char _Py_M__zipimport[] = { 124,1,160,4,124,2,161,1,1,0,87,0,110,40,4,0, 116,2,107,10,144,2,114,116,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,88,0,124,1,160,7,100,15,161,1,125,3, + 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,150,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,172,144,4,113,224,116,8,124,3, @@ -584,7 +584,7 @@ const unsigned char _Py_M__zipimport[] = { 125,22,122,14,124,1,160,7,124,19,161,1,125,23,87,0, 110,40,4,0,116,2,107,10,144,3,114,216,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,88,0,116,8,124,23,131,1, + 141,2,130,1,89,0,110,2,48,0,116,8,124,23,131,1, 124,19,107,3,144,3,114,250,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, @@ -592,490 +592,493 @@ const unsigned char _Py_M__zipimport[] = { 157,2,124,0,100,2,141,2,130,1,87,0,110,40,4,0, 116,2,107,10,144,4,114,84,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,88,0,124,13,100,28,64,0,144,4,114,106, + 89,0,110,2,48,0,124,13,100,28,64,0,144,4,114,106, 124,23,160,16,161,0,125,23,110,54,122,14,124,23,160,16, 100,29,161,1,125,23,87,0,110,38,4,0,116,17,107,10, 144,4,114,158,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,88,0, + 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,118, - 87,0,53,0,81,0,82,0,88,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,14,1,24,2,8, - 1,2,1,14,1,8,1,14,1,14,1,24,1,12,1,18, - 1,18,3,2,1,12,1,12,1,14,1,10,1,2,255,12, - 2,8,1,2,255,2,1,2,255,4,2,2,1,10,1,12, - 1,16,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,16,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,16, - 1,24,1,14,1,18,4,2,1,28,1,22,1,16,1,24, - 2,10,2,10,3,2,1,14,1,16,1,22,2,12,1,12, - 1,20,1,8,1,22,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,108,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,60,122,16,100,5,100, - 6,108,4,109,5,125,0,1,0,87,0,110,38,4,0,116, - 6,107,10,114,82,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,88,0,87,0,53,0,100,4,97,0,88,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,70,114,0,0,0,0,169,1,218, - 10,100,101,99,111,109,112,114,101,115,115,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,14, - 1,10,1,18,2,6,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,128,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,8,125,10,122,14, - 124,10,160,3,124,6,161,1,1,0,87,0,110,38,4,0, - 116,4,107,10,114,102,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,88,0,124,10,160,5,100,5,161,1,125,11,116,6, - 124,11,131,1,100,5,107,3,114,134,116,7,100,6,131,1, - 130,1,124,11,100,0,100,7,133,2,25,0,100,8,107,3, - 114,168,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,40,4,0,116,4,107,10,144,1, - 114,18,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,88,0, - 124,10,160,5,124,4,161,1,125,15,116,6,124,15,131,1, - 124,4,107,3,144,1,114,52,116,4,100,12,131,1,130,1, - 87,0,53,0,81,0,82,0,88,0,124,3,100,1,107,2, - 144,1,114,76,124,15,83,0,122,10,116,9,131,0,125,16, - 87,0,110,30,4,0,116,10,107,10,144,1,114,116,1,0, - 1,0,1,0,116,0,100,13,131,1,130,1,89,0,110,2, - 88,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,14,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,16,1,24,1,10,1,14,1,18,2,10,2,4,3, - 2,1,10,1,16,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,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,60,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,22,4,0,116,2,107,10, - 114,50,1,0,1,0,1,0,89,0,100,0,83,0,88,0, - 124,6,100,2,64,0,100,3,107,3,125,7,124,7,114,182, - 124,6,100,4,64,0,100,3,107,3,125,8,116,3,106,4, - 100,5,107,3,114,180,124,8,115,104,116,3,106,4,100,6, - 107,2,114,180,116,5,124,0,124,2,131,2,125,9,124,9, - 100,0,107,9,114,180,116,3,160,6,116,0,106,7,124,9, - 161,2,125,10,122,20,116,8,160,9,124,4,124,10,124,3, - 124,5,161,4,1,0,87,0,110,22,4,0,116,2,107,10, - 114,178,1,0,1,0,1,0,89,0,100,0,83,0,88,0, - 110,84,116,10,124,0,124,2,131,2,92,2,125,11,125,12, - 124,11,144,1,114,10,116,11,116,12,124,4,100,7,100,8, - 133,2,25,0,131,1,124,11,131,2,114,246,116,12,124,4, - 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, - 114,10,116,13,160,14,100,10,124,3,155,2,157,2,161,1, - 1,0,100,0,83,0,116,15,160,16,124,4,100,9,100,0, - 133,2,25,0,161,1,125,13,116,17,124,13,116,18,131,2, - 144,1,115,56,116,19,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,20,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,98,111,111,115,116,114,97,112,95,101,120,116,101,114,110, - 97,108,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,88,0,0,0,0,2,2,1,2,254,6,5, - 2,1,18,1,14,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,2,0,2,0,2,0,2,255, - 8,2,14,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, + 87,0,100,0,4,0,4,0,131,3,1,0,110,18,49,0, + 144,4,115,246,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,14,1,24,2,8,1,2,1,14,1,8,1,14,1,14, + 1,24,1,12,1,18,1,18,3,2,1,12,1,12,1,14, + 1,10,1,2,255,12,2,8,1,2,255,2,1,2,255,4, + 2,2,1,10,1,12,1,16,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,16,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,16,1,24,1,14,1,18,4,2,1,28, + 1,22,1,16,1,24,2,10,2,10,3,2,1,14,1,16, + 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,112,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, + 64,122,16,100,4,100,5,108,4,109,5,125,0,1,0,87, + 0,110,38,4,0,116,6,107,10,114,82,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,26,0,0,0,0,2,4,3,10, + 1,8,2,4,1,4,1,16,1,14,1,10,1,16,2,6, + 0,6,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,150,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,18,125,10,122,14,124,10,160,3, + 124,6,161,1,1,0,87,0,110,38,4,0,116,4,107,10, + 114,102,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,134,116,7,100,6,131,1,130,1,124,11, + 100,0,100,7,133,2,25,0,100,8,107,3,114,168,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,40,4,0,116,4,107,10,144,1,114,18,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,52,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,74, + 48,0,1,0,1,0,1,0,89,0,1,0,124,3,100,1, + 107,2,144,1,114,98,124,15,83,0,122,10,116,9,131,0, + 125,16,87,0,110,30,4,0,116,10,107,10,144,1,114,138, + 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,14,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,16,1,24,1,10,1,14,1,40,2,10,2, + 4,3,2,1,10,1,16,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, - 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,22,0, - 0,0,0,1,4,1,10,1,10,1,6,1,6,1,10,1, - 10,1,2,0,2,0,2,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,116,0,0,0,122,82,124,1,100, - 1,100,0,133,2,25,0,100,2,107,6,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,107,10,114,110,1,0,1, - 0,1,0,89,0,100,6,83,0,88,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,20,1,114,151,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,86,0,0,0,124,1, - 100,1,100,0,133,2,25,0,100,2,107,6,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,22,4,0, - 116,1,107,10,114,68,1,0,1,0,1,0,89,0,100,0, - 83,0,88,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,14, - 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,198,0,0,0,116,0,124,0,124,1,131,2,125,2, - 116,1,68,0,93,160,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,20,4,0,116,7, - 107,10,114,88,1,0,1,0,1,0,89,0,113,14,88,0, - 124,7,100,4,25,0,125,8,116,8,124,0,106,4,124,7, - 131,2,125,9,124,4,114,132,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,107,8,114,152,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,14,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,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,92,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,107,10,114,86,1,0,1,0,1, - 0,116,7,124,3,131,1,130,1,89,0,110,2,88,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,14,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,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, + 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, + 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,60,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,22,4,0,116,2, + 107,10,114,50,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,182,124,6,100,4,64,0,100,3,107,3,125,8,116,3, + 106,4,100,5,107,3,114,180,124,8,115,104,116,3,106,4, + 100,6,107,2,114,180,116,5,124,0,124,2,131,2,125,9, + 124,9,100,0,107,9,114,180,116,3,160,6,116,0,106,7, + 124,9,161,2,125,10,122,20,116,8,160,9,124,4,124,10, + 124,3,124,5,161,4,1,0,87,0,110,22,4,0,116,2, + 107,10,114,178,1,0,1,0,1,0,89,0,100,0,83,0, + 48,0,110,84,116,10,124,0,124,2,131,2,92,2,125,11, + 125,12,124,11,144,1,114,10,116,11,116,12,124,4,100,7, + 100,8,133,2,25,0,131,1,124,11,131,2,114,246,116,12, + 124,4,100,8,100,9,133,2,25,0,131,1,124,12,107,3, + 144,1,114,10,116,13,160,14,100,10,124,3,155,2,157,2, + 161,1,1,0,100,0,83,0,116,15,160,16,124,4,100,9, + 100,0,133,2,25,0,161,1,125,13,116,17,124,13,116,18, + 131,2,144,1,115,56,116,19,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,20,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,98,111,111,115,116,114,97,112,95,101,120,116,101, + 114,110,97,108,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,88,0,0,0,0,2,2,1,2,254, + 6,5,2,1,18,1,14,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,2,0,2,0,2,0, + 2,255,8,2,14,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, + 22,0,0,0,0,1,4,1,10,1,10,1,6,1,6,1, + 10,1,10,1,2,0,2,0,2,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,116,0,0,0,122,82,124, + 1,100,1,100,0,133,2,25,0,100,2,107,6,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,107,10,114,110,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,20,1,114,151,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,86,0,0,0, + 124,1,100,1,100,0,133,2,25,0,100,2,107,6,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,22, + 4,0,116,1,107,10,114,68,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,14,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,198,0,0,0,116,0,124,0,124,1,131,2, + 125,2,116,1,68,0,93,160,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,20,4,0, + 116,7,107,10,114,88,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,132,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,107,8,114,152,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,14,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,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,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,72,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,22,4,0,116,4, - 107,10,114,66,1,0,1,0,1,0,89,0,100,3,83,0, - 88,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,14,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,186,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,102,125,6,122, - 18,124,1,124,6,131,1,160,5,124,4,161,1,125,7,87, - 0,110,24,4,0,116,11,107,10,114,124,1,0,1,0,1, - 0,89,0,113,78,89,0,110,2,88,0,124,7,106,8,106, - 7,125,8,116,12,124,8,131,1,100,1,107,2,114,156,124, - 7,106,7,86,0,1,0,113,78,124,8,124,5,107,7,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, - 14,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, + 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,92,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,107,10,114,86,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,14,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,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,72,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,22,4,0, + 116,4,107,10,114,66,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,14,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,186,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,102,125, + 6,122,18,124,1,124,6,131,1,160,5,124,4,161,1,125, + 7,87,0,110,24,4,0,116,11,107,10,114,124,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, + 156,124,7,106,7,86,0,1,0,113,78,124,8,124,5,107, + 7,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,14,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, }; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index d39bad0bcd3b9..e4f4a8c779114 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -47,12 +47,12 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_RERAISE, + &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, - &&TARGET_BEGIN_FINALLY, + &&_unknown_opcode, &&TARGET_END_ASYNC_FOR, &&TARGET_INPLACE_ADD, &&TARGET_INPLACE_SUBTRACT, @@ -80,14 +80,14 @@ static void *opcode_targets[256] = { &&TARGET_INPLACE_XOR, &&TARGET_INPLACE_OR, &&_unknown_opcode, - &&TARGET_WITH_CLEANUP_START, - &&TARGET_WITH_CLEANUP_FINISH, + &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, &&TARGET_YIELD_VALUE, &&TARGET_POP_BLOCK, - &&TARGET_END_FINALLY, + &&_unknown_opcode, &&TARGET_POP_EXCEPT, &&TARGET_STORE_NAME, &&TARGET_DELETE_NAME, @@ -161,8 +161,8 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&TARGET_LOAD_METHOD, &&TARGET_CALL_METHOD, - &&TARGET_CALL_FINALLY, - &&TARGET_POP_FINALLY, + &&_unknown_opcode, + &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/peephole.c b/Python/peephole.c index d859648411fa3..714a4520ba8db 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -198,7 +198,6 @@ markblocks(_Py_CODEUNIT *code, Py_ssize_t len) case SETUP_FINALLY: case SETUP_WITH: case SETUP_ASYNC_WITH: - case CALL_FINALLY: j = GETJUMPTGT(code, i); assert(j < len); blocks[j] = 1; @@ -432,14 +431,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Remove unreachable ops after RETURN */ case RETURN_VALUE: h = i + 1; - /* END_FINALLY should be kept since it denotes the end of - the 'finally' block in frame_setlineno() in frameobject.c. - SETUP_FINALLY should be kept for balancing. - */ - while (h < codelen && ISBASICBLOCK(blocks, i, h) && - _Py_OPCODE(codestr[h]) != END_FINALLY) + while (h < codelen && ISBASICBLOCK(blocks, i, h)) { - if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY) { + /* Leave SETUP_FINALLY and RERAISE in place to help find block limits. */ + if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY || _Py_OPCODE(codestr[h]) == RERAISE) { while (h > i + 1 && _Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG) { @@ -506,7 +501,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case SETUP_FINALLY: case SETUP_WITH: case SETUP_ASYNC_WITH: - case CALL_FINALLY: j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1; j *= sizeof(_Py_CODEUNIT); break; From webhook-mailer at python.org Thu Nov 21 04:39:05 2019 From: webhook-mailer at python.org (Giampaolo Rodola) Date: Thu, 21 Nov 2019 09:39:05 -0000 Subject: [Python-checkins] CODEOWNERS: add myself for asyncore/chat, ftplib and shutil modules (#17313) Message-ID: https://github.com/python/cpython/commit/5c534da798eae58eec9ad0601a1c480b271e25a9 commit: 5c534da798eae58eec9ad0601a1c480b271e25a9 branch: master author: Giampaolo Rodola committer: GitHub date: 2019-11-21T17:38:51+08:00 summary: CODEOWNERS: add myself for asyncore/chat, ftplib and shutil modules (#17313) files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0df7b5d28d9b0..32d21143231e4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -93,6 +93,7 @@ Include/pytime.h @pganssle @abalkin /Tools/msi/ @python/windows-team /Tools/nuget/ @python/windows-team +# Misc **/*itertools* @rhettinger **/*collections* @rhettinger **/*random* @rhettinger @@ -108,6 +109,11 @@ Include/pytime.h @pganssle @abalkin **/*typing* @gvanrossum @ilevkivskyi +**/*asyncore @giampaolo +**/*asynchat @giampaolo +**/*ftplib @giampaolo +**/*shutil @giampaolo + # macOS /Mac/ @python/macos-team **/*osx_support* @python/macos-team From webhook-mailer at python.org Thu Nov 21 06:54:07 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 21 Nov 2019 11:54:07 -0000 Subject: [Python-checkins] bpo-38875: test_capi: trashcan tests require cpu resource (GH-17314) Message-ID: https://github.com/python/cpython/commit/0127bb1c5c3286f87e284ff6083133bfdcfd5a4f commit: 0127bb1c5c3286f87e284ff6083133bfdcfd5a4f branch: master author: Victor Stinner committer: GitHub date: 2019-11-21T12:54:02+01:00 summary: bpo-38875: test_capi: trashcan tests require cpu resource (GH-17314) test_capi: trashcan tests now require the test "cpu" resource. files: A Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 2024435109793..e65973c4646b1 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -351,9 +351,11 @@ def test_trashcan_subclass(self): for i in range(1000): L = MyList((L,)) + @support.requires_resource('cpu') def test_trashcan_python_class1(self): self.do_test_trashcan_python_class(list) + @support.requires_resource('cpu') def test_trashcan_python_class2(self): from _testcapi import MyList self.do_test_trashcan_python_class(MyList) diff --git a/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst b/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst new file mode 100644 index 0000000000000..3f6c86d32262c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst @@ -0,0 +1 @@ +test_capi: trashcan tests now require the test "cpu" resource. From webhook-mailer at python.org Thu Nov 21 06:54:58 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Thu, 21 Nov 2019 11:54:58 -0000 Subject: [Python-checkins] bpo-38692: Skip test_posix.test_pidfd_open() on EPERM (GH-17290) Message-ID: https://github.com/python/cpython/commit/3ab479a2d1959923c9ab80c227dd1f39720b4e2d commit: 3ab479a2d1959923c9ab80c227dd1f39720b4e2d branch: master author: Victor Stinner committer: GitHub date: 2019-11-21T12:54:54+01:00 summary: bpo-38692: Skip test_posix.test_pidfd_open() on EPERM (GH-17290) Skip the test_posix.test_pidfd_open() test if os.pidfd_open() fails with a PermissionError. This situation can happen in a Linux sandbox using a syscall whitelist which doesn't allow the pidfd_open() syscall yet (like systemd-nspawn). files: A Misc/NEWS.d/next/Tests/2019-11-20-15-42-06.bpo-38692.aqAvyF.rst M Lib/test/test_posix.py diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 98a39c3f04099..4df882b621085 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1476,6 +1476,8 @@ def test_pidfd_open(self): os.pidfd_open(-1) if cm.exception.errno == errno.ENOSYS: self.skipTest("system does not support pidfd_open") + if isinstance(cm.exception, PermissionError): + self.skipTest(f"pidfd_open syscall blocked: {cm.exception!r}") self.assertEqual(cm.exception.errno, errno.EINVAL) os.close(os.pidfd_open(os.getpid(), 0)) diff --git a/Misc/NEWS.d/next/Tests/2019-11-20-15-42-06.bpo-38692.aqAvyF.rst b/Misc/NEWS.d/next/Tests/2019-11-20-15-42-06.bpo-38692.aqAvyF.rst new file mode 100644 index 0000000000000..fa2056632ba8b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-20-15-42-06.bpo-38692.aqAvyF.rst @@ -0,0 +1,3 @@ +Skip the test_posix.test_pidfd_open() test if ``os.pidfd_open()`` fails with a +:exc:`PermissionError`. This situation can happen in a Linux sandbox using a +syscall whitelist which doesn't allow the ``pidfd_open()`` syscall yet. From webhook-mailer at python.org Thu Nov 21 07:11:48 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 12:11:48 -0000 Subject: [Python-checkins] bpo-38875: test_capi: trashcan tests require cpu resource (GH-17314) Message-ID: https://github.com/python/cpython/commit/767b42633bb7ac39dd6743d8dd7f5b5cc122acea commit: 767b42633bb7ac39dd6743d8dd7f5b5cc122acea branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-21T04:11:44-08:00 summary: bpo-38875: test_capi: trashcan tests require cpu resource (GH-17314) test_capi: trashcan tests now require the test "cpu" resource. (cherry picked from commit 0127bb1c5c3286f87e284ff6083133bfdcfd5a4f) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst M Lib/test/test_capi.py diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 78c51b3cb61e8..2761ab3f2095d 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -350,9 +350,11 @@ def test_trashcan_subclass(self): for i in range(1000): L = MyList((L,)) + @support.requires_resource('cpu') def test_trashcan_python_class1(self): self.do_test_trashcan_python_class(list) + @support.requires_resource('cpu') def test_trashcan_python_class2(self): from _testcapi import MyList self.do_test_trashcan_python_class(MyList) diff --git a/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst b/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst new file mode 100644 index 0000000000000..3f6c86d32262c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-11-21-09-11-06.bpo-38875.wSZJal.rst @@ -0,0 +1 @@ +test_capi: trashcan tests now require the test "cpu" resource. From webhook-mailer at python.org Thu Nov 21 09:47:56 2019 From: webhook-mailer at python.org (Mark Shannon) Date: Thu, 21 Nov 2019 14:47:56 -0000 Subject: [Python-checkins] Correct release version to 3.9 for RERAISE and WITH_EXCEPT_START bytecodes. (#17318) Message-ID: https://github.com/python/cpython/commit/82f897bf8f72d09f537054d64a94e645ad23d8d6 commit: 82f897bf8f72d09f537054d64a94e645ad23d8d6 branch: master author: Mark Shannon committer: GitHub date: 2019-11-21T14:47:49Z summary: Correct release version to 3.9 for RERAISE and WITH_EXCEPT_START bytecodes. (#17318) bpo-33387 Corrects commit fee5526 files: M Doc/library/dis.rst diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 2b55486f3a28e..1f540d95078f6 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -710,7 +710,7 @@ iterations of the loop. Re-raises the exception currently on top of the stack. - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. opcode:: WITH_EXCEPT_START @@ -720,7 +720,7 @@ iterations of the loop. Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception has occurred in a :keyword:`with` statement. - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. opcode:: LOAD_ASSERTION_ERROR From webhook-mailer at python.org Thu Nov 21 12:25:24 2019 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Thu, 21 Nov 2019 17:25:24 -0000 Subject: [Python-checkins] bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) Message-ID: https://github.com/python/cpython/commit/0aca3a3a1e68b4ca2d334ab5255dfc267719096e commit: 0aca3a3a1e68b4ca2d334ab5255dfc267719096e branch: master author: benedwards14 <53377856+benedwards14 at users.noreply.github.com> committer: Ivan Levkivskyi date: 2019-11-21T17:24:58Z summary: bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) https://bugs.python.org/issue37838 files: A Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst M Lib/test/ann_module.py M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/ann_module.py b/Lib/test/ann_module.py index 9e6b87dac40f5..0567d6de1b647 100644 --- a/Lib/test/ann_module.py +++ b/Lib/test/ann_module.py @@ -6,6 +6,7 @@ """ from typing import Optional +from functools import wraps __annotations__[1] = 2 @@ -51,3 +52,9 @@ def foo(x: int = 10): def bar(y: List[str]): x: str = 'yes' bar() + +def dec(func): + @wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 49417efe5111b..ccd617c1fdff0 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2778,6 +2778,16 @@ class HasForeignBaseClass(mod_generics_cache.A): gth = get_type_hints +class ForRefExample: + @ann_module.dec + def func(self: 'ForRefExample'): + pass + + @ann_module.dec + @ann_module.dec + def nested(self: 'ForRefExample'): + pass + class GetTypeHintTests(BaseTestCase): def test_get_type_hints_from_various_objects(self): @@ -2876,6 +2886,11 @@ def test_get_type_hints_ClassVar(self): 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) + def test_get_type_hints_wrapped_decoratored_func(self): + expects = {'self': ForRefExample} + self.assertEqual(gth(ForRefExample.func), expects) + self.assertEqual(gth(ForRefExample.nested), expects) + class GetUtilitiesTestCase(TestCase): def test_get_origin(self): diff --git a/Lib/typing.py b/Lib/typing.py index 27be37a369a92..5523ee01e1f99 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1234,7 +1234,11 @@ def get_type_hints(obj, globalns=None, localns=None): if isinstance(obj, types.ModuleType): globalns = obj.__dict__ else: - globalns = getattr(obj, '__globals__', {}) + nsobj = obj + # Find globalns for the unwrapped object. + while hasattr(nsobj, '__wrapped__'): + nsobj = nsobj.__wrapped__ + globalns = getattr(nsobj, '__globals__', {}) if localns is None: localns = globalns elif localns is None: diff --git a/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst new file mode 100644 index 0000000000000..96d804addeb60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst @@ -0,0 +1 @@ +:meth:`typing.get_type_hints` properly handles functions decorated with :meth:`functools.wraps`. From webhook-mailer at python.org Thu Nov 21 12:43:21 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 17:43:21 -0000 Subject: [Python-checkins] bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) Message-ID: https://github.com/python/cpython/commit/30e5bd8471d7531d051796c01e8ede01ade883dc commit: 30e5bd8471d7531d051796c01e8ede01ade883dc branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-21T09:43:13-08:00 summary: bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) https://bugs.python.org/issue37838 (cherry picked from commit 0aca3a3a1e68b4ca2d334ab5255dfc267719096e) Co-authored-by: benedwards14 <53377856+benedwards14 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst M Lib/test/ann_module.py M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/ann_module.py b/Lib/test/ann_module.py index 9e6b87dac40f5..0567d6de1b647 100644 --- a/Lib/test/ann_module.py +++ b/Lib/test/ann_module.py @@ -6,6 +6,7 @@ """ from typing import Optional +from functools import wraps __annotations__[1] = 2 @@ -51,3 +52,9 @@ def foo(x: int = 10): def bar(y: List[str]): x: str = 'yes' bar() + +def dec(func): + @wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index d8abc0ac96a10..087dc2a82f038 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1787,6 +1787,16 @@ class HasForeignBaseClass(mod_generics_cache.A): gth = get_type_hints +class ForRefExample: + @ann_module.dec + def func(self: 'ForRefExample'): + pass + + @ann_module.dec + @ann_module.dec + def nested(self: 'ForRefExample'): + pass + class GetTypeHintTests(BaseTestCase): def test_get_type_hints_from_various_objects(self): @@ -1885,6 +1895,11 @@ def test_get_type_hints_ClassVar(self): 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) + def test_get_type_hints_wrapped_decoratored_func(self): + expects = {'self': ForRefExample} + self.assertEqual(gth(ForRefExample.func), expects) + self.assertEqual(gth(ForRefExample.nested), expects) + class CollectionsAbcTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index ea8dea54a5a3d..607eb1f8fc31a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -981,7 +981,11 @@ def get_type_hints(obj, globalns=None, localns=None): if isinstance(obj, types.ModuleType): globalns = obj.__dict__ else: - globalns = getattr(obj, '__globals__', {}) + nsobj = obj + # Find globalns for the unwrapped object. + while hasattr(nsobj, '__wrapped__'): + nsobj = nsobj.__wrapped__ + globalns = getattr(nsobj, '__globals__', {}) if localns is None: localns = globalns elif localns is None: diff --git a/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst new file mode 100644 index 0000000000000..96d804addeb60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst @@ -0,0 +1 @@ +:meth:`typing.get_type_hints` properly handles functions decorated with :meth:`functools.wraps`. From webhook-mailer at python.org Thu Nov 21 12:43:46 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 17:43:46 -0000 Subject: [Python-checkins] bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) Message-ID: https://github.com/python/cpython/commit/9458c5c42bbe5fb6ef2393c9ee66f012a2c13ca3 commit: 9458c5c42bbe5fb6ef2393c9ee66f012a2c13ca3 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-21T09:43:42-08:00 summary: bpo-37838: get_type_hints for wrapped functions with forward reference (GH-17126) https://bugs.python.org/issue37838 (cherry picked from commit 0aca3a3a1e68b4ca2d334ab5255dfc267719096e) Co-authored-by: benedwards14 <53377856+benedwards14 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst M Lib/test/ann_module.py M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/ann_module.py b/Lib/test/ann_module.py index 9e6b87dac40f5..0567d6de1b647 100644 --- a/Lib/test/ann_module.py +++ b/Lib/test/ann_module.py @@ -6,6 +6,7 @@ """ from typing import Optional +from functools import wraps __annotations__[1] = 2 @@ -51,3 +52,9 @@ def foo(x: int = 10): def bar(y: List[str]): x: str = 'yes' bar() + +def dec(func): + @wraps(func) + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 104b7c035ca6e..ded5a8b39db3e 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2778,6 +2778,16 @@ class HasForeignBaseClass(mod_generics_cache.A): gth = get_type_hints +class ForRefExample: + @ann_module.dec + def func(self: 'ForRefExample'): + pass + + @ann_module.dec + @ann_module.dec + def nested(self: 'ForRefExample'): + pass + class GetTypeHintTests(BaseTestCase): def test_get_type_hints_from_various_objects(self): @@ -2876,6 +2886,11 @@ def test_get_type_hints_ClassVar(self): 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) + def test_get_type_hints_wrapped_decoratored_func(self): + expects = {'self': ForRefExample} + self.assertEqual(gth(ForRefExample.func), expects) + self.assertEqual(gth(ForRefExample.nested), expects) + class GetUtilitiesTestCase(TestCase): def test_get_origin(self): diff --git a/Lib/typing.py b/Lib/typing.py index bd30da90ad796..69f6d9873490a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1234,7 +1234,11 @@ def get_type_hints(obj, globalns=None, localns=None): if isinstance(obj, types.ModuleType): globalns = obj.__dict__ else: - globalns = getattr(obj, '__globals__', {}) + nsobj = obj + # Find globalns for the unwrapped object. + while hasattr(nsobj, '__wrapped__'): + nsobj = nsobj.__wrapped__ + globalns = getattr(nsobj, '__globals__', {}) if localns is None: localns = globalns elif localns is None: diff --git a/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst new file mode 100644 index 0000000000000..96d804addeb60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-21-11-39-17.bpo-37838.lRFcEC.rst @@ -0,0 +1 @@ +:meth:`typing.get_type_hints` properly handles functions decorated with :meth:`functools.wraps`. From webhook-mailer at python.org Thu Nov 21 13:14:36 2019 From: webhook-mailer at python.org (Andrew Svetlov) Date: Thu, 21 Nov 2019 18:14:36 -0000 Subject: [Python-checkins] [3.8] bpo-38857: AsyncMock fix for awaitable values and StopIteration fix [3.8] (GH-17269) (#17304) Message-ID: https://github.com/python/cpython/commit/b2744c1be73f5af0d2dc4b952389efc90c8de94e commit: b2744c1be73f5af0d2dc4b952389efc90c8de94e branch: 3.8 author: Lisa Roach committer: Andrew Svetlov date: 2019-11-21T20:14:32+02:00 summary: [3.8] bpo-38857: AsyncMock fix for awaitable values and StopIteration fix [3.8] (GH-17269) (#17304) (cherry picked from commit 046442d02bcc6e848e71e93e47f6cde9e279e993) Co-authored-by: Jason Fried files: A Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst A Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst M Doc/library/unittest.mock.rst M Lib/unittest/mock.py M Lib/unittest/test/testmock/testasync.py diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 746cf765b077f..ebfaf7d643956 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -873,7 +873,7 @@ object:: exception, - if ``side_effect`` is an iterable, the async function will return the next value of the iterable, however, if the sequence of result is - exhausted, ``StopIteration`` is raised immediately, + exhausted, ``StopAsyncIteration`` is raised immediately, - if ``side_effect`` is not defined, the async function will return the value defined by ``return_value``, hence, by default, the async function returns a new :class:`AsyncMock` object. diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 488ab1c23de42..d6e30679456a5 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1125,8 +1125,8 @@ def _increment_mock_call(self, /, *args, **kwargs): _new_parent = _new_parent._mock_new_parent def _execute_mock_call(self, /, *args, **kwargs): - # seperate from _increment_mock_call so that awaited functions are - # executed seperately from their call + # separate from _increment_mock_call so that awaited functions are + # executed separately from their call, also AsyncMock overrides this method effect = self.side_effect if effect is not None: @@ -2122,29 +2122,45 @@ def __init__(self, /, *args, **kwargs): code_mock.co_flags = inspect.CO_COROUTINE self.__dict__['__code__'] = code_mock - async def _mock_call(self, /, *args, **kwargs): - try: - result = super()._mock_call(*args, **kwargs) - except (BaseException, StopIteration) as e: - side_effect = self.side_effect - if side_effect is not None and not callable(side_effect): - raise - return await _raise(e) + async def _execute_mock_call(self, /, *args, **kwargs): + # This is nearly just like super(), except for sepcial handling + # of coroutines _call = self.call_args + self.await_count += 1 + self.await_args = _call + self.await_args_list.append(_call) - async def proxy(): - try: - if inspect.isawaitable(result): - return await result - else: - return result - finally: - self.await_count += 1 - self.await_args = _call - self.await_args_list.append(_call) + effect = self.side_effect + if effect is not None: + if _is_exception(effect): + raise effect + elif not _callable(effect): + try: + result = next(effect) + except StopIteration: + # It is impossible to propogate a StopIteration + # through coroutines because of PEP 479 + raise StopAsyncIteration + if _is_exception(result): + raise result + elif asyncio.iscoroutinefunction(effect): + result = await effect(*args, **kwargs) + else: + result = effect(*args, **kwargs) - return await proxy() + if result is not DEFAULT: + return result + + if self._mock_return_value is not DEFAULT: + return self.return_value + + if self._mock_wraps is not None: + if asyncio.iscoroutinefunction(self._mock_wraps): + return await self._mock_wraps(*args, **kwargs) + return self._mock_wraps(*args, **kwargs) + + return self.return_value def assert_awaited(self): """ @@ -2852,10 +2868,6 @@ def seal(mock): seal(m) -async def _raise(exception): - raise exception - - class _AsyncIterator: """ Wraps an iterator in an asynchronous iterator. diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 7671d55a8cfba..be8e3117c466b 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -353,42 +353,84 @@ def test_magicmock_lambda_spec(self): self.assertIsInstance(cm, MagicMock) -class AsyncArguments(unittest.TestCase): - def test_add_return_value(self): +class AsyncArguments(unittest.IsolatedAsyncioTestCase): + async def test_add_return_value(self): async def addition(self, var): return var + 1 mock = AsyncMock(addition, return_value=10) - output = asyncio.run(mock(5)) + output = await mock(5) self.assertEqual(output, 10) - def test_add_side_effect_exception(self): + async def test_add_side_effect_exception(self): async def addition(var): return var + 1 mock = AsyncMock(addition, side_effect=Exception('err')) with self.assertRaises(Exception): - asyncio.run(mock(5)) + await mock(5) - def test_add_side_effect_function(self): + async def test_add_side_effect_function(self): async def addition(var): return var + 1 mock = AsyncMock(side_effect=addition) - result = asyncio.run(mock(5)) + result = await mock(5) self.assertEqual(result, 6) - def test_add_side_effect_iterable(self): + async def test_add_side_effect_iterable(self): vals = [1, 2, 3] mock = AsyncMock(side_effect=vals) for item in vals: - self.assertEqual(item, asyncio.run(mock())) - - with self.assertRaises(RuntimeError) as e: - asyncio.run(mock()) - self.assertEqual( - e.exception, - RuntimeError('coroutine raised StopIteration') - ) + self.assertEqual(item, await mock()) + + with self.assertRaises(StopAsyncIteration) as e: + await mock() + + async def test_return_value_AsyncMock(self): + value = AsyncMock(return_value=10) + mock = AsyncMock(return_value=value) + result = await mock() + self.assertIs(result, value) + + async def test_return_value_awaitable(self): + fut = asyncio.Future() + fut.set_result(None) + mock = AsyncMock(return_value=fut) + result = await mock() + self.assertIsInstance(result, asyncio.Future) + + async def test_side_effect_awaitable_values(self): + fut = asyncio.Future() + fut.set_result(None) + + mock = AsyncMock(side_effect=[fut]) + result = await mock() + self.assertIsInstance(result, asyncio.Future) + + with self.assertRaises(StopAsyncIteration): + await mock() + + async def test_side_effect_is_AsyncMock(self): + effect = AsyncMock(return_value=10) + mock = AsyncMock(side_effect=effect) + + result = await mock() + self.assertEqual(result, 10) + + async def test_wraps_coroutine(self): + value = asyncio.Future() + + ran = False + async def inner(): + nonlocal ran + ran = True + return value + + mock = AsyncMock(wraps=inner) + result = await mock() + self.assertEqual(result, value) + mock.assert_awaited() + self.assertTrue(ran) class AsyncMagicMethods(unittest.TestCase): def test_async_magic_methods_return_async_mocks(self): diff --git a/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst b/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst new file mode 100644 index 0000000000000..f28df2811fb78 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-19-16-28-25.bpo-38857.YPUkU9.rst @@ -0,0 +1,4 @@ +AsyncMock fix for return values that are awaitable types. This also covers +side_effect iterable values that happend to be awaitable, and wraps +callables that return an awaitable type. Before these awaitables were being +awaited instead of being returned as is. diff --git a/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst b/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst new file mode 100644 index 0000000000000..c059539a1de60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-19-16-30-46.bpo-38859.AZUzL8.rst @@ -0,0 +1,3 @@ +AsyncMock now returns StopAsyncIteration on the exaustion of a side_effects +iterable. Since PEP-479 its Impossible to raise a StopIteration exception +from a coroutine. From webhook-mailer at python.org Thu Nov 21 16:23:20 2019 From: webhook-mailer at python.org (Jason R. Coombs) Date: Thu, 21 Nov 2019 21:23:20 -0000 Subject: [Python-checkins] bpo-38526: Fix zipfile.Path method name to be the correct one (#17317) Message-ID: https://github.com/python/cpython/commit/65444cf7fe84d8ca1f9b51c7f5992210751e08bb commit: 65444cf7fe84d8ca1f9b51c7f5992210751e08bb branch: master author: Claudiu Popa committer: Jason R. Coombs date: 2019-11-21T16:23:13-05:00 summary: bpo-38526: Fix zipfile.Path method name to be the correct one (#17317) files: M Doc/library/zipfile.rst diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 18d2e9a60a7ba..e8a2530fb8c17 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -494,7 +494,7 @@ Path objects are traversable using the ``/`` operator. Invoke :meth:`ZipFile.open` on the current path. Accepts the same arguments as :meth:`ZipFile.open`. -.. method:: Path.listdir() +.. method:: Path.iterdir() Enumerate the children of the current directory. From webhook-mailer at python.org Thu Nov 21 16:41:26 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 21 Nov 2019 21:41:26 -0000 Subject: [Python-checkins] bpo-38526: Fix zipfile.Path method name to be the correct one (GH-17317) Message-ID: https://github.com/python/cpython/commit/107ed88cde3ae6f1cb01ae75575ea0f92c138464 commit: 107ed88cde3ae6f1cb01ae75575ea0f92c138464 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-21T13:41:20-08:00 summary: bpo-38526: Fix zipfile.Path method name to be the correct one (GH-17317) (cherry picked from commit 65444cf7fe84d8ca1f9b51c7f5992210751e08bb) Co-authored-by: Claudiu Popa files: M Doc/library/zipfile.rst diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 18d2e9a60a7ba..e8a2530fb8c17 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -494,7 +494,7 @@ Path objects are traversable using the ``/`` operator. Invoke :meth:`ZipFile.open` on the current path. Accepts the same arguments as :meth:`ZipFile.open`. -.. method:: Path.listdir() +.. method:: Path.iterdir() Enumerate the children of the current directory. From webhook-mailer at python.org Thu Nov 21 16:47:26 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Thu, 21 Nov 2019 21:47:26 -0000 Subject: [Python-checkins] [3.7] bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) (GH-17224) Message-ID: https://github.com/python/cpython/commit/91c15a542cb780377dcde8fc17ba93111bc1d1cf commit: 91c15a542cb780377dcde8fc17ba93111bc1d1cf branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Vinay Sajip date: 2019-11-21T21:47:22Z summary: [3.7] bpo-16576: Add checks for bitfields passed by value to functions. (GH-17097) (GH-17224) (cherry picked from commit 106271568c58cfebae58f0c52b640dbe716ba2ce) files: M Lib/ctypes/test/test_structures.py M Modules/_ctypes/_ctypes.c M Modules/_ctypes/_ctypes_test.c diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 8e2897ad51230..c129377041f03 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -612,6 +612,87 @@ class Test5(Structure): self.assertEqual(test5.nested.an_int, 0) self.assertEqual(test5.another_int, 0) + #@unittest.skipIf('s390' in MACHINE, 'Test causes segfault on S390') + def test_bitfield_by_value(self): + # See bpo-16576 + + # These should mirror the structures in Modules/_ctypes/_ctypes_test.c + + class Test6(Structure): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test6 = Test6() + # As these are signed int fields, all are logically -1 due to sign + # extension. + test6.A = 1 + test6.B = 3 + test6.C = 7 + test6.D = 3 + dll = CDLL(_ctypes_test.__file__) + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value1 + func.restype = c_long + func.argtypes = (Test6,) + result = func(test6) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a struct/union with a bitfield by value, which is ' + 'unsupported.') + # passing by reference should be OK + func = dll._testfunc_bitfield_by_reference1 + func.restype = c_long + func.argtypes = (POINTER(Test6),) + result = func(byref(test6)) + self.assertEqual(result, -4) + self.assertEqual(test6.A, 0) + self.assertEqual(test6.B, 0) + self.assertEqual(test6.C, 0) + self.assertEqual(test6.D, 0) + + class Test7(Structure): + _fields_ = [ + ('A', c_uint, 1), + ('B', c_uint, 2), + ('C', c_uint, 3), + ('D', c_uint, 2), + ] + test7 = Test7() + test7.A = 1 + test7.B = 3 + test7.C = 7 + test7.D = 3 + func = dll._testfunc_bitfield_by_reference2 + func.restype = c_long + func.argtypes = (POINTER(Test7),) + result = func(byref(test7)) + self.assertEqual(result, 14) + self.assertEqual(test7.A, 0) + self.assertEqual(test7.B, 0) + self.assertEqual(test7.C, 0) + self.assertEqual(test7.D, 0) + + # for a union with bitfields, the union check happens first + class Test8(Union): + _fields_ = [ + ('A', c_int, 1), + ('B', c_int, 2), + ('C', c_int, 3), + ('D', c_int, 2), + ] + + test8 = Test8() + with self.assertRaises(TypeError) as ctx: + func = dll._testfunc_bitfield_by_value2 + func.restype = c_long + func.argtypes = (Test8,) + result = func(test8) + self.assertEqual(ctx.exception.args[0], 'item 1 in _argtypes_ passes ' + 'a union by value, which is unsupported.') + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 0e209c33a80af..c8fed44599543 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2276,16 +2276,13 @@ converters_from_argtypes(PyObject *ob) for (i = 0; i < nArgs; ++i) { PyObject *tp = PyTuple_GET_ITEM(ob, i); - PyObject *cnv = PyObject_GetAttrString(tp, "from_param"); - if (!cnv) - goto argtypes_error_1; + PyObject *cnv; StgDictObject *stgdict = PyType_stgdict(tp); if (stgdict != NULL) { if (stgdict->flags & TYPEFLAG_HASUNION) { Py_DECREF(converters); Py_DECREF(ob); - Py_DECREF(cnv); if (!PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "item %zd in _argtypes_ passes a union by " @@ -2294,12 +2291,22 @@ converters_from_argtypes(PyObject *ob) } return NULL; } - /* if (stgdict->flags & TYPEFLAG_HASBITFIELD) { - printf("found stgdict with bitfield\n"); + Py_DECREF(converters); + Py_DECREF(ob); + if (!PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + "item %zd in _argtypes_ passes a struct/" + "union with a bitfield by value, which is " + "unsupported.", + i + 1); + } + return NULL; } - */ } + cnv = PyObject_GetAttrString(tp, "from_param"); + if (!cnv) + goto argtypes_error_1; PyTuple_SET_ITEM(converters, i, cnv); } Py_DECREF(ob); diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index e06a045545578..d08a011e944ad 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -198,6 +198,56 @@ _testfunc_union_by_reference3(Test5 *in) { return result; } +typedef struct { + signed int A: 1, B:2, C:3, D:2; +} Test6; + +EXPORT(long) +_testfunc_bitfield_by_value1(Test6 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + +EXPORT(long) +_testfunc_bitfield_by_reference1(Test6 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test6)); + return result; +} + +typedef struct { + unsigned int A: 1, B:2, C:3, D:2; +} Test7; + +EXPORT(long) +_testfunc_bitfield_by_reference2(Test7 *in) { + long result = in->A + in->B + in->C + in->D; + + memset(in, 0, sizeof(Test7)); + return result; +} + +typedef union { + signed int A: 1, B:2, C:3, D:2; +} Test8; + +EXPORT(long) +_testfunc_bitfield_by_value2(Test8 in) { + long result = in.A + in.B + in.C + in.D; + + /* As the struct is passed by value, changes to it shouldn't be + * reflected in the caller. + */ + memset(&in, 0, sizeof(in)); + return result; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", From webhook-mailer at python.org Fri Nov 22 01:52:07 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Fri, 22 Nov 2019 06:52:07 -0000 Subject: [Python-checkins] Defer import of shutil which only needed for help and usage (GH-17334) Message-ID: https://github.com/python/cpython/commit/b4e5eeac267c436bb60776dc5be771d3259bd298 commit: b4e5eeac267c436bb60776dc5be771d3259bd298 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-21T22:51:45-08:00 summary: Defer import of shutil which only needed for help and usage (GH-17334) files: M Lib/argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 5a8eff2f4cc89..5d3ce2ad709f0 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -87,7 +87,6 @@ import os as _os import re as _re -import shutil as _shutil import sys as _sys from gettext import gettext as _, ngettext @@ -167,7 +166,8 @@ def __init__(self, # default setting for width if width is None: - width = _shutil.get_terminal_size().columns + import shutil + width = shutil.get_terminal_size().columns width -= 2 self._prog = prog @@ -264,7 +264,7 @@ def add_argument(self, action): invocations.append(get_invocation(subaction)) # update the maximum item length - invocation_length = max([len(s) for s in invocations]) + invocation_length = max(map(len, invocations)) action_length = invocation_length + self._current_indent self._action_max_length = max(self._action_max_length, action_length) From webhook-mailer at python.org Fri Nov 22 04:13:11 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 09:13:11 -0000 Subject: [Python-checkins] bpo-38863: Improve is_cgi() in http.server (GH-17312) Message-ID: https://github.com/python/cpython/commit/91daa9d7224626dad4bb820924c01b3438ca6e3f commit: 91daa9d7224626dad4bb820924c01b3438ca6e3f branch: master author: Siwon Kang committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-22T01:13:05-08:00 summary: bpo-38863: Improve is_cgi() in http.server (GH-17312) is_cgi() function of http.server library does not currently handle a cgi script if one of the cgi_directories is located at the sub-directory of given path. Since is_cgi() in CGIHTTPRequestHandler class separates given path into (dir, rest) based on the first seen '/', multi-level directories like /sub/dir/cgi-bin/hello.py is divided into head=/sub, rest=dir/cgi-bin/hello.py then check whether '/sub' exists in cgi_directories = [..., '/sub/dir/cgi-bin']. This patch makes the is_cgi() keep expanding dir part to the next '/' then checking if that expanded path exists in the cgi_directories. Signed-off-by: Siwon Kang https://bugs.python.org/issue38863 files: A Misc/NEWS.d/next/Library/2019-11-21-16-30-00.bpo-38863.RkdTjf.rst M Lib/http/server.py M Lib/test/test_httpservers.py diff --git a/Lib/http/server.py b/Lib/http/server.py index 005dd824f9a71..47a4fcf9a6518 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1014,8 +1014,10 @@ def is_cgi(self): """ collapsed_path = _url_collapse_path(self.path) dir_sep = collapsed_path.find('/', 1) - head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] - if head in self.cgi_directories: + while dir_sep > 0 and not collapsed_path[:dir_sep] in self.cgi_directories: + dir_sep = collapsed_path.find('/', dir_sep+1) + if dir_sep > 0: + head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] self.cgi_info = head, tail return True return False diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 1c980a2fa66ea..26da71e0b2701 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -601,13 +601,20 @@ def setUp(self): self.parent_dir = tempfile.mkdtemp() self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin') self.cgi_child_dir = os.path.join(self.cgi_dir, 'child-dir') + self.sub_dir_1 = os.path.join(self.parent_dir, 'sub') + self.sub_dir_2 = os.path.join(self.sub_dir_1, 'dir') + self.cgi_dir_in_sub_dir = os.path.join(self.sub_dir_2, 'cgi-bin') os.mkdir(self.cgi_dir) os.mkdir(self.cgi_child_dir) + os.mkdir(self.sub_dir_1) + os.mkdir(self.sub_dir_2) + os.mkdir(self.cgi_dir_in_sub_dir) self.nocgi_path = None self.file1_path = None self.file2_path = None self.file3_path = None self.file4_path = None + self.file5_path = None # The shebang line should be pure ASCII: use symlink if possible. # See issue #7668. @@ -652,6 +659,11 @@ def setUp(self): file4.write(cgi_file4 % (self.pythonexe, 'QUERY_STRING')) os.chmod(self.file4_path, 0o777) + self.file5_path = os.path.join(self.cgi_dir_in_sub_dir, 'file5.py') + with open(self.file5_path, 'w', encoding='utf-8') as file5: + file5.write(cgi_file1 % self.pythonexe) + os.chmod(self.file5_path, 0o777) + os.chdir(self.parent_dir) def tearDown(self): @@ -669,8 +681,13 @@ def tearDown(self): os.remove(self.file3_path) if self.file4_path: os.remove(self.file4_path) + if self.file5_path: + os.remove(self.file5_path) os.rmdir(self.cgi_child_dir) os.rmdir(self.cgi_dir) + os.rmdir(self.cgi_dir_in_sub_dir) + os.rmdir(self.sub_dir_2) + os.rmdir(self.sub_dir_1) os.rmdir(self.parent_dir) finally: BaseTestCase.tearDown(self) @@ -789,6 +806,13 @@ def test_query_with_continuous_slashes(self): 'text/html', HTTPStatus.OK), (res.read(), res.getheader('Content-type'), res.status)) + def test_cgi_path_in_sub_directories(self): + CGIHTTPRequestHandler.cgi_directories.append('/sub/dir/cgi-bin') + res = self.request('/sub/dir/cgi-bin/file5.py') + self.assertEqual( + (b'Hello World' + self.linesep, 'text/html', HTTPStatus.OK), + (res.read(), res.getheader('Content-type'), res.status)) + class SocketlessRequestHandler(SimpleHTTPRequestHandler): def __init__(self, directory=None): diff --git a/Misc/NEWS.d/next/Library/2019-11-21-16-30-00.bpo-38863.RkdTjf.rst b/Misc/NEWS.d/next/Library/2019-11-21-16-30-00.bpo-38863.RkdTjf.rst new file mode 100644 index 0000000000000..6b621eeea2fb6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-21-16-30-00.bpo-38863.RkdTjf.rst @@ -0,0 +1,2 @@ +Improve :func:`is_cgi` function in :mod:`http.server`, which enables processing +the case that cgi directory is a child of another directory other than root. From webhook-mailer at python.org Fri Nov 22 04:58:04 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 09:58:04 -0000 Subject: [Python-checkins] bpo-36854: Fix refleak in subinterpreter (GH-17331) Message-ID: https://github.com/python/cpython/commit/310e2d25170a88ef03f6fd31efcc899fe062da2c commit: 310e2d25170a88ef03f6fd31efcc899fe062da2c branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T10:58:00+01:00 summary: bpo-36854: Fix refleak in subinterpreter (GH-17331) finalize_interp_clear() now explicitly clears the codec registry and then trigger a GC collection to clear all references. files: M Modules/_testcapimodule.c M Python/pylifecycle.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index baa6907b7e4f6..0908f3457f580 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6721,11 +6721,14 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); + PyObject *v; #ifdef WITH_PYMALLOC - PyModule_AddObject(m, "WITH_PYMALLOC", Py_True); + v = Py_True; #else - PyModule_AddObject(m, "WITH_PYMALLOC", Py_False); + v = Py_False; #endif + Py_INCREF(v); + PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7591f069b455d..8c508e33800ef 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1210,6 +1210,14 @@ finalize_interp_clear(PyThreadState *tstate) { int is_main_interp = _Py_IsMainInterpreter(tstate); + /* bpo-36854: Explicitly clear the codec registry + and trigger a GC collection */ + PyInterpreterState *interp = tstate->interp; + Py_CLEAR(interp->codec_search_path); + Py_CLEAR(interp->codec_search_cache); + Py_CLEAR(interp->codec_error_registry); + _PyGC_CollectNoFail(); + /* Clear interpreter state and all thread states */ PyInterpreterState_Clear(tstate->interp); From webhook-mailer at python.org Fri Nov 22 06:27:57 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 11:27:57 -0000 Subject: [Python-checkins] bpo-38858: Call _PyUnicode_Fini() in Py_EndInterpreter() (GH-17330) Message-ID: https://github.com/python/cpython/commit/3d4833488a173c16446c3f94f58f05e2d13c5dee commit: 3d4833488a173c16446c3f94f58f05e2d13c5dee branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T12:27:50+01:00 summary: bpo-38858: Call _PyUnicode_Fini() in Py_EndInterpreter() (GH-17330) Py_EndInterpreter() now clears the filesystem codec. files: M Include/internal/pycore_pylifecycle.h M Objects/unicodeobject.c M Python/pylifecycle.c diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index c837bcdbc03cc..73aa5ef1f6cab 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -77,7 +77,7 @@ extern void _PyImport_Fini2(void); extern void _PyGC_Fini(PyThreadState *tstate); extern void _PyType_Fini(void); extern void _Py_HashRandomization_Fini(void); -extern void _PyUnicode_Fini(void); +extern void _PyUnicode_Fini(PyThreadState *tstate); extern void _PyLong_Fini(void); extern void _PyFaulthandler_Fini(void); extern void _PyHash_Fini(void); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5ae0af8ea336a..89e45d01e3789 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15929,34 +15929,37 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) void -_PyUnicode_Fini(void) +_PyUnicode_Fini(PyThreadState *tstate) { + if (_Py_IsMainInterpreter(tstate)) { #if defined(WITH_VALGRIND) || defined(__INSURE__) - /* Insure++ is a memory analysis tool that aids in discovering - * memory leaks and other memory problems. On Python exit, the - * interned string dictionaries are flagged as being in use at exit - * (which it is). Under normal circumstances, this is fine because - * the memory will be automatically reclaimed by the system. Under - * memory debugging, it's a huge source of useless noise, so we - * trade off slower shutdown for less distraction in the memory - * reports. -baw - */ - unicode_release_interned(); + /* Insure++ is a memory analysis tool that aids in discovering + * memory leaks and other memory problems. On Python exit, the + * interned string dictionaries are flagged as being in use at exit + * (which it is). Under normal circumstances, this is fine because + * the memory will be automatically reclaimed by the system. Under + * memory debugging, it's a huge source of useless noise, so we + * trade off slower shutdown for less distraction in the memory + * reports. -baw + */ + unicode_release_interned(); #endif /* __INSURE__ */ - Py_CLEAR(unicode_empty); + Py_CLEAR(unicode_empty); - for (Py_ssize_t i = 0; i < 256; i++) { - Py_CLEAR(unicode_latin1[i]); + for (Py_ssize_t i = 0; i < 256; i++) { + Py_CLEAR(unicode_latin1[i]); + } + _PyUnicode_ClearStaticStrings(); + (void)PyUnicode_ClearFreeList(); } - _PyUnicode_ClearStaticStrings(); - (void)PyUnicode_ClearFreeList(); PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); PyMem_RawFree(interp->fs_codec.encoding); interp->fs_codec.encoding = NULL; PyMem_RawFree(interp->fs_codec.errors); interp->fs_codec.errors = NULL; + interp->config.filesystem_errors = _Py_ERROR_UNKNOWN; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8c508e33800ef..5f3c49a680439 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1182,9 +1182,6 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PySet_Fini(); _PyBytes_Fini(); _PyLong_Fini(); - } - - if (is_main_interp) { _PyFloat_Fini(); _PyDict_Fini(); _PySlice_Fini(); @@ -1197,9 +1194,12 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PyArg_Fini(); _PyAsyncGen_Fini(); _PyContext_Fini(); + } + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(tstate); - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(); + if (is_main_interp) { _Py_ClearFileSystemEncoding(); } } From webhook-mailer at python.org Fri Nov 22 07:39:55 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 12:39:55 -0000 Subject: [Python-checkins] bpo-36854: Fix reference counter in PyInit__testcapi() (GH-17338) Message-ID: https://github.com/python/cpython/commit/84c36c152a2bdf98f9cc7ce0e1db98e1f442a05e commit: 84c36c152a2bdf98f9cc7ce0e1db98e1f442a05e branch: 3.8 author: Victor Stinner committer: GitHub date: 2019-11-22T13:39:36+01:00 summary: bpo-36854: Fix reference counter in PyInit__testcapi() (GH-17338) Increment properly Py_True/Py_False reference counter for _testcapi.WITH_PYMALLOC variable. files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 46d772cff608e..b54071669cf99 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -6283,11 +6283,14 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); + PyObject *v; #ifdef WITH_PYMALLOC - PyModule_AddObject(m, "WITH_PYMALLOC", Py_True); + v = Py_True; #else - PyModule_AddObject(m, "WITH_PYMALLOC", Py_False); + v = Py_False; #endif + Py_INCREF(v); + PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); From webhook-mailer at python.org Fri Nov 22 07:52:03 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Fri, 22 Nov 2019 12:52:03 -0000 Subject: [Python-checkins] bpo-38866: Remove asyncore from test_pyclbr.py (GH-17316) Message-ID: https://github.com/python/cpython/commit/138e7bbb0a5ed44bdd54605e8c58c8f3d3865321 commit: 138e7bbb0a5ed44bdd54605e8c58c8f3d3865321 branch: master author: jacksonriley <52106215+jacksonriley at users.noreply.github.com> committer: Inada Naoki date: 2019-11-22T21:51:58+09:00 summary: bpo-38866: Remove asyncore from test_pyclbr.py (GH-17316) Co-Authored-By: Kyle Stanley files: M Lib/test/test_pyclbr.py diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 4385271cd0f2b..869799cfa9a66 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -247,7 +247,7 @@ def test_dotted_name_not_a_package(self): # not a package. # # Issue #14798. - self.assertRaises(ImportError, pyclbr.readmodule_ex, 'asyncore.foo') + self.assertRaises(ImportError, pyclbr.readmodule_ex, 'asyncio.foo') def test_module_has_no_spec(self): module_name = "doesnotexist" From webhook-mailer at python.org Fri Nov 22 07:57:03 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 12:57:03 -0000 Subject: [Python-checkins] bpo-36854: Fix reference counter in PyInit__testcapi() (GH-17338) Message-ID: https://github.com/python/cpython/commit/bff525566469021949910deec84e837306b79886 commit: bff525566469021949910deec84e837306b79886 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T04:56:59-08:00 summary: bpo-36854: Fix reference counter in PyInit__testcapi() (GH-17338) Increment properly Py_True/Py_False reference counter for _testcapi.WITH_PYMALLOC variable. (cherry picked from commit 84c36c152a2bdf98f9cc7ce0e1db98e1f442a05e) Co-authored-by: Victor Stinner files: M Modules/_testcapimodule.c diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 64b7b69049394..16ea9c2d66554 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5444,11 +5444,14 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); + PyObject *v; #ifdef WITH_PYMALLOC - PyModule_AddObject(m, "WITH_PYMALLOC", Py_True); + v = Py_True; #else - PyModule_AddObject(m, "WITH_PYMALLOC", Py_False); + v = Py_False; #endif + Py_INCREF(v); + PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); From webhook-mailer at python.org Fri Nov 22 08:48:28 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 13:48:28 -0000 Subject: [Python-checkins] Fix quoted signature of setattrofunc (GH-17251) Message-ID: https://github.com/python/cpython/commit/4e205b74f91400c0e6810e79370a99e29a28d599 commit: 4e205b74f91400c0e6810e79370a99e29a28d599 branch: master author: Alex <637714+alexchandel at users.noreply.github.com> committer: Victor Stinner date: 2019-11-22T14:48:14+01:00 summary: Fix quoted signature of setattrofunc (GH-17251) setattrofunc returns `int`, not `PyObject *`. files: M Doc/c-api/typeobj.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index b4ffd6b41c628..7b205c044953b 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -955,7 +955,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The signature is the same as for :c:func:`PyObject_SetAttr`:: - PyObject *tp_setattro(PyObject *self, PyObject *attr, PyObject *value); + int tp_setattro(PyObject *self, PyObject *attr, PyObject *value); In addition, setting *value* to ``NULL`` to delete an attribute must be supported. It is usually convenient to set this field to From webhook-mailer at python.org Fri Nov 22 09:15:40 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 14:15:40 -0000 Subject: [Python-checkins] bpo-22367: Update test_fcntl.py for spawn process mode (GH-17154) (GH-17252) Message-ID: https://github.com/python/cpython/commit/c3cd0de9ec7ab54186cebef5b2edfd098f7ae387 commit: c3cd0de9ec7ab54186cebef5b2edfd098f7ae387 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Victor Stinner date: 2019-11-22T15:15:36+01:00 summary: bpo-22367: Update test_fcntl.py for spawn process mode (GH-17154) (GH-17252) (cherry picked from commit 9960230f76eb555d6dfbe8a324efed35610c85f9) Co-authored-by: Dong-hee Na files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 88d989d5e358d..c394f6945a8d2 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -51,6 +51,21 @@ def __init__(self, fn): def fileno(self): return self.fn +def try_lockf_on_other_process_fail(fname, cmd): + f = open(fname, 'wb+') + try: + fcntl.lockf(f, cmd) + except BlockingIOError: + pass + finally: + f.close() + +def try_lockf_on_other_process(fname, cmd): + f = open(fname, 'wb+') + fcntl.lockf(f, cmd) + fcntl.lockf(f, fcntl.LOCK_UN) + f.close() + class TestFcntl(unittest.TestCase): def setUp(self): @@ -138,28 +153,23 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") def test_lockf_exclusive(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_EX | fcntl.LOCK_NB - def try_lockf_on_other_process(): - self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) - fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process) + p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) self.assertEqual(p.exitcode, 0) + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") def test_lockf_share(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_SH | fcntl.LOCK_NB - def try_lockf_on_other_process(): - fcntl.lockf(self.f, cmd) - fcntl.lockf(self.f, fcntl.LOCK_UN) - fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process) + p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) From webhook-mailer at python.org Fri Nov 22 09:15:46 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 14:15:46 -0000 Subject: [Python-checkins] bpo-22367: Update test_fcntl.py for spawn process mode (GH-17154) (GH-17253) Message-ID: https://github.com/python/cpython/commit/d4d79209e69d52ea4c047545c6c60c3ba75f15f4 commit: d4d79209e69d52ea4c047545c6c60c3ba75f15f4 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Victor Stinner date: 2019-11-22T15:15:42+01:00 summary: bpo-22367: Update test_fcntl.py for spawn process mode (GH-17154) (GH-17253) (cherry picked from commit 9960230f76eb555d6dfbe8a324efed35610c85f9) Co-authored-by: Dong-hee Na files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 30eeb6dc4d02a..036bd64b40511 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -51,6 +51,21 @@ def __init__(self, fn): def fileno(self): return self.fn +def try_lockf_on_other_process_fail(fname, cmd): + f = open(fname, 'wb+') + try: + fcntl.lockf(f, cmd) + except BlockingIOError: + pass + finally: + f.close() + +def try_lockf_on_other_process(fname, cmd): + f = open(fname, 'wb+') + fcntl.lockf(f, cmd) + fcntl.lockf(f, fcntl.LOCK_UN) + f.close() + class TestFcntl(unittest.TestCase): def setUp(self): @@ -138,28 +153,23 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") def test_lockf_exclusive(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_EX | fcntl.LOCK_NB - def try_lockf_on_other_process(): - self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) - fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process) + p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) self.assertEqual(p.exitcode, 0) + @unittest.skipIf(platform.system() == "AIX", "AIX returns PermissionError") def test_lockf_share(self): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_SH | fcntl.LOCK_NB - def try_lockf_on_other_process(): - fcntl.lockf(self.f, cmd) - fcntl.lockf(self.f, fcntl.LOCK_UN) - fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process) + p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) From webhook-mailer at python.org Fri Nov 22 09:22:18 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 14:22:18 -0000 Subject: [Python-checkins] bpo-38804: Fix REDoS in http.cookiejar (GH-17157) Message-ID: https://github.com/python/cpython/commit/1b779bfb8593739b11cbb988ef82a883ec9d077e commit: 1b779bfb8593739b11cbb988ef82a883ec9d077e branch: master author: bcaller committer: Victor Stinner date: 2019-11-22T15:22:11+01:00 summary: bpo-38804: Fix REDoS in http.cookiejar (GH-17157) The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar to parse Set-Cookie headers returned by a server. Processing a response from a malicious HTTP server can lead to extreme CPU usage and execution will be blocked for a long time. The regex contained multiple overlapping \s* capture groups. Ignoring the ?-optional capture groups the regex could be simplified to \d+-\w+-\d+(\s*\s*\s*)$ Therefore, a long sequence of spaces can trigger bad performance. Matching a malicious string such as LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!") caused catastrophic backtracking. The fix removes ambiguity about which \s* should match a particular space. You can create a malicious server which responds with Set-Cookie headers to attack all python programs which access it e.g. from http.server import BaseHTTPRequestHandler, HTTPServer def make_set_cookie_value(n_spaces): spaces = " " * n_spaces expiry = f"1-c-1{spaces}!" return f"b;Expires={expiry}" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.log_request(204) self.send_response_only(204) # Don't bother sending Server and Date n_spaces = ( int(self.path[1:]) # Can GET e.g. /100 to test shorter sequences if len(self.path) > 1 else 65506 # Max header line length 65536 ) value = make_set_cookie_value(n_spaces) for i in range(99): # Not necessary, but we can have up to 100 header lines self.send_header("Set-Cookie", value) self.end_headers() if __name__ == "__main__": HTTPServer(("", 44020), Handler).serve_forever() This server returns 99 Set-Cookie headers. Each has 65506 spaces. Extracting the cookies will pretty much never complete. Vulnerable client using the example at the bottom of https://docs.python.org/3/library/http.cookiejar.html : import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) r = opener.open("http://localhost:44020/") The popular requests library was also vulnerable without any additional options (as it uses http.cookiejar by default): import requests requests.get("http://localhost:44020/") * Regression test for http.cookiejar REDoS If we regress, this test will take a very long time. * Improve performance of http.cookiejar.ISO_DATE_RE A string like "444444" + (" " * 2000) + "A" could cause poor performance due to the 2 overlapping \s* groups, although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was. files: A Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst M Lib/http/cookiejar.py M Lib/test/test_http_cookiejar.py M Misc/ACKS diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index adc7ed62425d0..47ed5c3d64ab7 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -214,10 +214,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -287,9 +291,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 853a40044965b..2d7077af6da39 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -123,6 +123,13 @@ def test_http2time_garbage(self): "http2time(%s) is not None\n" "http2time(test) %s" % (test, http2time(test))) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + def test_iso2time(self): def parse_date(text): return time.gmtime(iso2time(text))[:6] @@ -180,6 +187,12 @@ def test_iso2time_garbage(self): self.assertIsNone(iso2time(test), "iso2time(%r)" % test) + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index 13c6676bace1f..357ce024e9e8c 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -250,6 +250,7 @@ Zach Byrne Vedran ?a?i? Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst new file mode 100644 index 0000000000000..1f45142d9f743 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst @@ -0,0 +1 @@ +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. From webhook-mailer at python.org Fri Nov 22 09:42:14 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 14:42:14 -0000 Subject: [Python-checkins] bpo-38804: Fix REDoS in http.cookiejar (GH-17157) Message-ID: https://github.com/python/cpython/commit/a1e1be4c4969c7c20c8c958e5ab5279ae6a66a16 commit: a1e1be4c4969c7c20c8c958e5ab5279ae6a66a16 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T06:42:06-08:00 summary: bpo-38804: Fix REDoS in http.cookiejar (GH-17157) The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar to parse Set-Cookie headers returned by a server. Processing a response from a malicious HTTP server can lead to extreme CPU usage and execution will be blocked for a long time. The regex contained multiple overlapping \s* capture groups. Ignoring the ?-optional capture groups the regex could be simplified to \d+-\w+-\d+(\s*\s*\s*)$ Therefore, a long sequence of spaces can trigger bad performance. Matching a malicious string such as LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!") caused catastrophic backtracking. The fix removes ambiguity about which \s* should match a particular space. You can create a malicious server which responds with Set-Cookie headers to attack all python programs which access it e.g. from http.server import BaseHTTPRequestHandler, HTTPServer def make_set_cookie_value(n_spaces): spaces = " " * n_spaces expiry = f"1-c-1{spaces}!" return f"b;Expires={expiry}" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.log_request(204) self.send_response_only(204) GH- Don't bother sending Server and Date n_spaces = ( int(self.path[1:]) GH- Can GET e.g. /100 to test shorter sequences if len(self.path) > 1 else 65506 GH- Max header line length 65536 ) value = make_set_cookie_value(n_spaces) for i in range(99): GH- Not necessary, but we can have up to 100 header lines self.send_header("Set-Cookie", value) self.end_headers() if __name__ == "__main__": HTTPServer(("", 44020), Handler).serve_forever() This server returns 99 Set-Cookie headers. Each has 65506 spaces. Extracting the cookies will pretty much never complete. Vulnerable client using the example at the bottom of https://docs.python.org/3/library/http.cookiejar.html : import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) r = opener.open("http://localhost:44020/") The popular requests library was also vulnerable without any additional options (as it uses http.cookiejar by default): import requests requests.get("http://localhost:44020/") * Regression test for http.cookiejar REDoS If we regress, this test will take a very long time. * Improve performance of http.cookiejar.ISO_DATE_RE A string like "444444" + (" " * 2000) + "A" could cause poor performance due to the 2 overlapping \s* groups, although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was. (cherry picked from commit 1b779bfb8593739b11cbb988ef82a883ec9d077e) Co-authored-by: bcaller files: A Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst M Lib/http/cookiejar.py M Lib/test/test_http_cookiejar.py M Misc/ACKS diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index adc7ed62425d0..47ed5c3d64ab7 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -214,10 +214,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -287,9 +291,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 853a40044965b..2d7077af6da39 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -123,6 +123,13 @@ def test_http2time_garbage(self): "http2time(%s) is not None\n" "http2time(test) %s" % (test, http2time(test))) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + def test_iso2time(self): def parse_date(text): return time.gmtime(iso2time(text))[:6] @@ -180,6 +187,12 @@ def test_iso2time_garbage(self): self.assertIsNone(iso2time(test), "iso2time(%r)" % test) + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index a2e8046313f0a..e52ae984f1571 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -250,6 +250,7 @@ Zach Byrne Vedran ?a?i? Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst new file mode 100644 index 0000000000000..1f45142d9f743 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst @@ -0,0 +1 @@ +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. From webhook-mailer at python.org Fri Nov 22 09:42:18 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 14:42:18 -0000 Subject: [Python-checkins] bpo-38804: Fix REDoS in http.cookiejar (GH-17157) Message-ID: https://github.com/python/cpython/commit/cb6085138a845f8324adc011b65754acc2086cc0 commit: cb6085138a845f8324adc011b65754acc2086cc0 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T06:42:13-08:00 summary: bpo-38804: Fix REDoS in http.cookiejar (GH-17157) The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar to parse Set-Cookie headers returned by a server. Processing a response from a malicious HTTP server can lead to extreme CPU usage and execution will be blocked for a long time. The regex contained multiple overlapping \s* capture groups. Ignoring the ?-optional capture groups the regex could be simplified to \d+-\w+-\d+(\s*\s*\s*)$ Therefore, a long sequence of spaces can trigger bad performance. Matching a malicious string such as LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!") caused catastrophic backtracking. The fix removes ambiguity about which \s* should match a particular space. You can create a malicious server which responds with Set-Cookie headers to attack all python programs which access it e.g. from http.server import BaseHTTPRequestHandler, HTTPServer def make_set_cookie_value(n_spaces): spaces = " " * n_spaces expiry = f"1-c-1{spaces}!" return f"b;Expires={expiry}" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.log_request(204) self.send_response_only(204) GH- Don't bother sending Server and Date n_spaces = ( int(self.path[1:]) GH- Can GET e.g. /100 to test shorter sequences if len(self.path) > 1 else 65506 GH- Max header line length 65536 ) value = make_set_cookie_value(n_spaces) for i in range(99): GH- Not necessary, but we can have up to 100 header lines self.send_header("Set-Cookie", value) self.end_headers() if __name__ == "__main__": HTTPServer(("", 44020), Handler).serve_forever() This server returns 99 Set-Cookie headers. Each has 65506 spaces. Extracting the cookies will pretty much never complete. Vulnerable client using the example at the bottom of https://docs.python.org/3/library/http.cookiejar.html : import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) r = opener.open("http://localhost:44020/") The popular requests library was also vulnerable without any additional options (as it uses http.cookiejar by default): import requests requests.get("http://localhost:44020/") * Regression test for http.cookiejar REDoS If we regress, this test will take a very long time. * Improve performance of http.cookiejar.ISO_DATE_RE A string like "444444" + (" " * 2000) + "A" could cause poor performance due to the 2 overlapping \s* groups, although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was. (cherry picked from commit 1b779bfb8593739b11cbb988ef82a883ec9d077e) Co-authored-by: bcaller files: A Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst M Lib/http/cookiejar.py M Lib/test/test_http_cookiejar.py M Misc/ACKS diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index 1bed893b1e266..d43a2193f9128 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -213,10 +213,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -286,9 +290,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 6eabeeae999d8..ff86ffa98c3ee 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -123,6 +123,13 @@ def test_http2time_garbage(self): "http2time(%s) is not None\n" "http2time(test) %s" % (test, http2time(test))) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + def test_iso2time(self): def parse_date(text): return time.gmtime(iso2time(text))[:6] @@ -180,6 +187,12 @@ def test_iso2time_garbage(self): self.assertIsNone(iso2time(test), "iso2time(%r)" % test) + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index 7afc92e7bb767..ad012eae7a323 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -245,6 +245,7 @@ Zach Byrne Vedran ?a?i? Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst new file mode 100644 index 0000000000000..1f45142d9f743 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst @@ -0,0 +1 @@ +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. From webhook-mailer at python.org Fri Nov 22 10:19:19 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 15:19:19 -0000 Subject: [Python-checkins] bpo-38858: Add init_set_builtins_open() subfunction (GH-17346) Message-ID: https://github.com/python/cpython/commit/e0c9ab8e26d1648b870b80c296b2490a5e9553e5 commit: e0c9ab8e26d1648b870b80c296b2490a5e9553e5 branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T16:19:14+01:00 summary: bpo-38858: Add init_set_builtins_open() subfunction (GH-17346) files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 5f3c49a680439..4825b8b28e621 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -64,6 +64,7 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward declarations */ static PyStatus add_main_module(PyInterpreterState *interp); static PyStatus init_import_site(void); +static PyStatus init_set_builtins_open(PyThreadState *tstate); static PyStatus init_sys_streams(PyThreadState *tstate); static PyStatus init_signals(PyThreadState *tstate); static void call_py_exitfuncs(PyThreadState *tstate); @@ -994,6 +995,11 @@ pyinit_main(PyThreadState *tstate) return status; } + status = init_set_builtins_open(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + /* Initialize warnings. */ PyObject *warnoptions = PySys_GetObject("warnoptions"); if (warnoptions != NULL && PyList_Size(warnoptions) > 0) @@ -1569,6 +1575,11 @@ new_interpreter(PyThreadState **tstate_p) return status; } + status = init_set_builtins_open(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = add_main_module(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -1891,12 +1902,49 @@ create_stdio(const PyConfig *config, PyObject* io, return NULL; } -/* Initialize sys.stdin, stdout, stderr and builtins.open */ +/* Set builtins.open to io.OpenWrapper */ static PyStatus -init_sys_streams(PyThreadState *tstate) +init_set_builtins_open(PyThreadState *tstate) { PyObject *iomod = NULL, *wrapper; PyObject *bimod = NULL; + PyStatus res = _PyStatus_OK(); + + if (!(iomod = PyImport_ImportModule("io"))) { + goto error; + } + + if (!(bimod = PyImport_ImportModule("builtins"))) { + goto error; + } + + if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { + goto error; + } + + /* Set builtins.open */ + if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { + Py_DECREF(wrapper); + goto error; + } + Py_DECREF(wrapper); + goto done; + +error: + res = _PyStatus_ERR("can't initialize io.open"); + +done: + Py_XDECREF(bimod); + Py_XDECREF(iomod); + return res; +} + + +/* Initialize sys.stdin, stdout, stderr and builtins.open */ +static PyStatus +init_sys_streams(PyThreadState *tstate) +{ + PyObject *iomod = NULL; PyObject *m; PyObject *std = NULL; int fd; @@ -1929,23 +1977,9 @@ init_sys_streams(PyThreadState *tstate) } Py_DECREF(m); - if (!(bimod = PyImport_ImportModule("builtins"))) { - goto error; - } - if (!(iomod = PyImport_ImportModule("io"))) { goto error; } - if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { - goto error; - } - - /* Set builtins.open */ - if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { - Py_DECREF(wrapper); - goto error; - } - Py_DECREF(wrapper); /* Set sys.stdin */ fd = fileno(stdin); @@ -2013,8 +2047,6 @@ init_sys_streams(PyThreadState *tstate) done: _Py_ClearStandardStreamEncoding(); - - Py_XDECREF(bimod); Py_XDECREF(iomod); return res; } From webhook-mailer at python.org Fri Nov 22 11:52:52 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 16:52:52 -0000 Subject: [Python-checkins] bpo-38858: Add init_interp_main() subfunction (GH-17347) Message-ID: https://github.com/python/cpython/commit/b00513636c9891deba4cae50217e25e8faf6c6ac commit: b00513636c9891deba4cae50217e25e8faf6c6ac branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T17:52:42+01:00 summary: bpo-38858: Add init_interp_main() subfunction (GH-17347) Fix new_interpreter() error handling: undo it all if status is an exception. files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 4825b8b28e621..e692d75999d6b 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -260,6 +260,7 @@ _Py_LegacyLocaleDetected(int warn) #endif } +#ifndef MS_WINDOWS static const char *_C_LOCALE_WARNING = "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " @@ -274,6 +275,7 @@ emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) PySys_FormatStderr("%s", _C_LOCALE_WARNING); } } +#endif /* !defined(MS_WINDOWS) */ typedef struct _CandidateLocale { const char *locale_name; /* The locale to try as a coercion target */ @@ -896,16 +898,16 @@ pyinit_core(_PyRuntimeState *runtime, configuration. Example of bpo-34008: Py_Main() called after Py_Initialize(). */ static PyStatus -_Py_ReconfigureMainInterpreter(PyInterpreterState *interp) +_Py_ReconfigureMainInterpreter(PyThreadState *tstate) { - PyConfig *config = &interp->config; + PyConfig *config = &tstate->interp->config; PyObject *argv = _PyWideStringList_AsList(&config->argv); if (argv == NULL) { return _PyStatus_NO_MEMORY(); \ } - int res = PyDict_SetItemString(interp->sysdict, "argv", argv); + int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv); Py_DECREF(argv); if (res < 0) { return _PyStatus_ERR("fail to set sys.argv"); @@ -913,60 +915,48 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) return _PyStatus_OK(); } -/* Update interpreter state based on supplied configuration settings - * - * After calling this function, most of the restrictions on the interpreter - * are lifted. The only remaining incomplete settings are those related - * to the main module (sys.argv[0], __main__ metadata) - * - * Calling this when the interpreter is not initializing, is already - * initialized or without a valid current thread state is a fatal error. - * Other errors should be reported as normal Python exceptions with a - * non-zero return code. - */ + static PyStatus -pyinit_main(PyThreadState *tstate) +init_interp_main(PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; - if (!runtime->core_initialized) { - return _PyStatus_ERR("runtime core not initialized"); - } - - /* Configure the main interpreter */ + PyStatus status; + int is_main_interp = _Py_IsMainInterpreter(tstate); PyInterpreterState *interp = tstate->interp; PyConfig *config = &interp->config; - if (runtime->initialized) { - return _Py_ReconfigureMainInterpreter(interp); - } - if (!config->_install_importlib) { /* Special mode for freeze_importlib: run with no import system * * This means anything which needs support from extension modules * or pure Python code in the standard library won't work. */ - runtime->initialized = 1; + if (is_main_interp) { + interp->runtime->initialized = 1; + } return _PyStatus_OK(); } - if (_PyTime_Init() < 0) { - return _PyStatus_ERR("can't initialize time"); - } + if (is_main_interp) { + if (_PyTime_Init() < 0) { + return _PyStatus_ERR("can't initialize time"); + } - if (_PySys_InitMain(tstate) < 0) { - return _PyStatus_ERR("can't finish initializing sys"); + if (_PySys_InitMain(tstate) < 0) { + return _PyStatus_ERR("can't finish initializing sys"); + } } - PyStatus status = init_importlib_external(tstate); + status = init_importlib_external(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - /* initialize the faulthandler module */ - status = _PyFaulthandler_Init(config->faulthandler); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (is_main_interp) { + /* initialize the faulthandler module */ + status = _PyFaulthandler_Init(config->faulthandler); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } status = _PyUnicode_InitEncodings(tstate); @@ -974,45 +964,49 @@ pyinit_main(PyThreadState *tstate) return status; } - if (config->install_signal_handlers) { - status = init_signals(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (is_main_interp) { + if (config->install_signal_handlers) { + status = init_signals(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - } - if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { - return _PyStatus_ERR("can't initialize tracemalloc"); + if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { + return _PyStatus_ERR("can't initialize tracemalloc"); + } } - status = add_main_module(interp); + status = init_sys_streams(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_sys_streams(tstate); + status = init_set_builtins_open(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_set_builtins_open(tstate); + status = add_main_module(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - /* Initialize warnings. */ - PyObject *warnoptions = PySys_GetObject("warnoptions"); - if (warnoptions != NULL && PyList_Size(warnoptions) > 0) - { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (warnings_module == NULL) { - fprintf(stderr, "'import warnings' failed; traceback:\n"); - _PyErr_Print(tstate); + if (is_main_interp) { + /* Initialize warnings. */ + PyObject *warnoptions = PySys_GetObject("warnoptions"); + if (warnoptions != NULL && PyList_Size(warnoptions) > 0) + { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + _PyErr_Print(tstate); + } + Py_XDECREF(warnings_module); } - Py_XDECREF(warnings_module); - } - runtime->initialized = 1; + interp->runtime->initialized = 1; + } if (config->site_import) { status = init_import_site(); @@ -1021,14 +1015,47 @@ pyinit_main(PyThreadState *tstate) } } + if (is_main_interp) { #ifndef MS_WINDOWS - emit_stderr_warning_for_legacy_locale(runtime); + emit_stderr_warning_for_legacy_locale(interp->runtime); #endif + } return _PyStatus_OK(); } +/* Update interpreter state based on supplied configuration settings + * + * After calling this function, most of the restrictions on the interpreter + * are lifted. The only remaining incomplete settings are those related + * to the main module (sys.argv[0], __main__ metadata) + * + * Calling this when the interpreter is not initializing, is already + * initialized or without a valid current thread state is a fatal error. + * Other errors should be reported as normal Python exceptions with a + * non-zero return code. + */ +static PyStatus +pyinit_main(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + if (!interp->runtime->core_initialized) { + return _PyStatus_ERR("runtime core not initialized"); + } + + if (interp->runtime->initialized) { + return _Py_ReconfigureMainInterpreter(tstate); + } + + PyStatus status = init_interp_main(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + + PyStatus _Py_InitializeMain(void) { @@ -1440,6 +1467,7 @@ Py_Finalize(void) Py_FinalizeEx(); } + /* Create and initialize a new interpreter and thread, and return the new thread. This requires that Py_Initialize() has been called first. @@ -1499,7 +1527,7 @@ new_interpreter(PyThreadState **tstate_p) status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } config = &interp->config; @@ -1508,7 +1536,8 @@ new_interpreter(PyThreadState **tstate_p) /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); if (modules == NULL) { - return _PyStatus_ERR("can't make modules dictionary"); + status = _PyStatus_ERR("can't make modules dictionary"); + goto done; } interp->modules = modules; @@ -1516,101 +1545,78 @@ new_interpreter(PyThreadState **tstate_p) if (sysmod != NULL) { interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) { - goto handle_error; + goto handle_exc; } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); if (_PySys_InitMain(tstate) < 0) { - return _PyStatus_ERR("can't finish initializing sys"); + status = _PyStatus_ERR("can't finish initializing sys"); + goto done; } } else if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) - goto handle_error; + goto handle_exc; Py_INCREF(interp->builtins); } else if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } if (bimod != NULL && sysmod != NULL) { status = _PyBuiltins_AddExceptions(bimod); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = _PySys_SetPreliminaryStderr(interp->sysdict); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = init_importlib(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } - status = init_importlib_external(tstate); + status = init_interp_main(tstate); if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyUnicode_InitEncodings(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = init_sys_streams(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = init_set_builtins_open(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = add_main_module(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (config->site_import) { - status = init_import_site(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + goto done; } } if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } *tstate_p = tstate; return _PyStatus_OK(); -handle_error: - /* Oops, it didn't work. Undo it all. */ +handle_exc: + status = _PyStatus_OK(); +done: + *tstate_p = NULL; + + /* Oops, it didn't work. Undo it all. */ PyErr_PrintEx(0); PyThreadState_Clear(tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); PyThreadState_Swap(save_tstate); - *tstate_p = NULL; - return _PyStatus_OK(); + return status; } PyThreadState * From webhook-mailer at python.org Fri Nov 22 11:57:19 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 22 Nov 2019 16:57:19 -0000 Subject: [Python-checkins] closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) Message-ID: https://github.com/python/cpython/commit/42bc60ead39c7be9f6bb7329977826e962f601eb commit: 42bc60ead39c7be9f6bb7329977826e962f601eb branch: master author: Callum Ward committer: Benjamin Peterson date: 2019-11-22T08:57:14-08:00 summary: closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) The Y2K reference is not needed as it only points out that Python's use of C standard functions doesn't generally suffer from Y2K issues; the point regarding conventions for conversion of 2-digit years in :func:`strptime` is still valid. files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 65ab679669eb3..e628ac44e8064 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -42,17 +42,12 @@ An explanation of some terminology and conventions is in order. library; for 32-bit systems, it is typically in 2038. .. index:: - single: Year 2000 - single: Y2K + single: 2-digit years -.. _time-y2kissues: - -* **Year 2000 (Y2K) issues**: Python depends on the platform's C library, which - generally doesn't have year 2000 issues, since all dates and times are - represented internally as seconds since the epoch. Function :func:`strptime` - can parse 2-digit years when given ``%y`` format code. When 2-digit years are - parsed, they are converted according to the POSIX and ISO C standards: values - 69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068. +* Function :func:`strptime` can parse 2-digit years when given ``%y`` format + code. When 2-digit years are parsed, they are converted according to the POSIX + and ISO C standards: values 69--99 are mapped to 1969--1999, and values 0--68 + are mapped to 2000--2068. .. index:: single: UTC From webhook-mailer at python.org Fri Nov 22 12:03:08 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 17:03:08 -0000 Subject: [Python-checkins] closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) Message-ID: https://github.com/python/cpython/commit/c58a8116475fc9e90fe87b150cde4e535173ec1c commit: c58a8116475fc9e90fe87b150cde4e535173ec1c branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T09:03:04-08:00 summary: closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) The Y2K reference is not needed as it only points out that Python's use of C standard functions doesn't generally suffer from Y2K issues; the point regarding conventions for conversion of 2-digit years in :func:`strptime` is still valid. (cherry picked from commit 42bc60ead39c7be9f6bb7329977826e962f601eb) Co-authored-by: Callum Ward files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 17f8cfc546147..c0f336fcbe429 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -42,17 +42,12 @@ An explanation of some terminology and conventions is in order. library; for 32-bit systems, it is typically in 2038. .. index:: - single: Year 2000 - single: Y2K + single: 2-digit years -.. _time-y2kissues: - -* **Year 2000 (Y2K) issues**: Python depends on the platform's C library, which - generally doesn't have year 2000 issues, since all dates and times are - represented internally as seconds since the epoch. Function :func:`strptime` - can parse 2-digit years when given ``%y`` format code. When 2-digit years are - parsed, they are converted according to the POSIX and ISO C standards: values - 69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068. +* Function :func:`strptime` can parse 2-digit years when given ``%y`` format + code. When 2-digit years are parsed, they are converted according to the POSIX + and ISO C standards: values 69--99 are mapped to 1969--1999, and values 0--68 + are mapped to 2000--2068. .. index:: single: UTC From webhook-mailer at python.org Fri Nov 22 12:03:55 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 17:03:55 -0000 Subject: [Python-checkins] closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) Message-ID: https://github.com/python/cpython/commit/ca5fafc2bbda9373c9ab12b76d17614585cffc23 commit: ca5fafc2bbda9373c9ab12b76d17614585cffc23 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T09:03:50-08:00 summary: closes bpo-29275: Remove Y2K reference from time module docs (GH-17321) The Y2K reference is not needed as it only points out that Python's use of C standard functions doesn't generally suffer from Y2K issues; the point regarding conventions for conversion of 2-digit years in :func:`strptime` is still valid. (cherry picked from commit 42bc60ead39c7be9f6bb7329977826e962f601eb) Co-authored-by: Callum Ward files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 65ab679669eb3..e628ac44e8064 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -42,17 +42,12 @@ An explanation of some terminology and conventions is in order. library; for 32-bit systems, it is typically in 2038. .. index:: - single: Year 2000 - single: Y2K + single: 2-digit years -.. _time-y2kissues: - -* **Year 2000 (Y2K) issues**: Python depends on the platform's C library, which - generally doesn't have year 2000 issues, since all dates and times are - represented internally as seconds since the epoch. Function :func:`strptime` - can parse 2-digit years when given ``%y`` format code. When 2-digit years are - parsed, they are converted according to the POSIX and ISO C standards: values - 69--99 are mapped to 1969--1999, and values 0--68 are mapped to 2000--2068. +* Function :func:`strptime` can parse 2-digit years when given ``%y`` format + code. When 2-digit years are parsed, they are converted according to the POSIX + and ISO C standards: values 69--99 are mapped to 1969--1999, and values 0--68 + are mapped to 2000--2068. .. index:: single: UTC From webhook-mailer at python.org Fri Nov 22 12:52:32 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 17:52:32 -0000 Subject: [Python-checkins] bpo-38858: _PyImport_FixupExtensionObject() handles subinterpreters (GH-17350) Message-ID: https://github.com/python/cpython/commit/82c83bd907409c287a5bd0d0f4598f2c0538f34d commit: 82c83bd907409c287a5bd0d0f4598f2c0538f34d branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T18:52:27+01:00 summary: bpo-38858: _PyImport_FixupExtensionObject() handles subinterpreters (GH-17350) If _PyImport_FixupExtensionObject() is called from a subinterpreter, leave extensions unchanged and don't copy the module dictionary into def->m_base.m_copy. files: M Include/cpython/pystate.h M Include/internal/pycore_pystate.h M Python/import.c M Python/pystate.c diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 6c8d2ae041ea5..d1792575c9737 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -147,7 +147,6 @@ struct _ts { The caller must hold the GIL.*/ PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void); -PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*); PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); /* Similar to PyThreadState_Get(), but don't issue a fatal error diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 936e9cbc65f7a..aa2103f07c795 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -324,6 +324,12 @@ extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); + +PyAPI_FUNC(int) _PyState_AddModule( + PyThreadState *tstate, + PyObject* module, + struct PyModuleDef* def); + #ifdef __cplusplus } #endif diff --git a/Python/import.c b/Python/import.c index ac3d10cfed226..923c6d0465d2e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -695,50 +695,62 @@ int _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, PyObject *filename, PyObject *modules) { - PyObject *dict, *key; - struct PyModuleDef *def; - int res; - if (extensions == NULL) { - extensions = PyDict_New(); - if (extensions == NULL) - return -1; - } if (mod == NULL || !PyModule_Check(mod)) { PyErr_BadInternalCall(); return -1; } - def = PyModule_GetDef(mod); + + struct PyModuleDef *def = PyModule_GetDef(mod); if (!def) { PyErr_BadInternalCall(); return -1; } - if (PyObject_SetItem(modules, name, mod) < 0) + + PyThreadState *tstate = _PyThreadState_GET(); + if (PyObject_SetItem(modules, name, mod) < 0) { return -1; - if (_PyState_AddModule(mod, def) < 0) { + } + if (_PyState_AddModule(tstate, mod, def) < 0) { PyMapping_DelItem(modules, name); return -1; } - if (def->m_size == -1) { - if (def->m_base.m_copy) { - /* Somebody already imported the module, - likely under a different name. - XXX this should really not happen. */ - Py_CLEAR(def->m_base.m_copy); + + if (_Py_IsMainInterpreter(tstate)) { + if (def->m_size == -1) { + if (def->m_base.m_copy) { + /* Somebody already imported the module, + likely under a different name. + XXX this should really not happen. */ + Py_CLEAR(def->m_base.m_copy); + } + PyObject *dict = PyModule_GetDict(mod); + if (dict == NULL) { + return -1; + } + def->m_base.m_copy = PyDict_Copy(dict); + if (def->m_base.m_copy == NULL) { + return -1; + } } - dict = PyModule_GetDict(mod); - if (dict == NULL) + + if (extensions == NULL) { + extensions = PyDict_New(); + if (extensions == NULL) { + return -1; + } + } + + PyObject *key = PyTuple_Pack(2, filename, name); + if (key == NULL) { return -1; - def->m_base.m_copy = PyDict_Copy(dict); - if (def->m_base.m_copy == NULL) + } + int res = PyDict_SetItem(extensions, key, (PyObject *)def); + Py_DECREF(key); + if (res < 0) { return -1; + } } - key = PyTuple_Pack(2, filename, name); - if (key == NULL) - return -1; - res = PyDict_SetItem(extensions, key, (PyObject *)def); - Py_DECREF(key); - if (res < 0) - return -1; + return 0; } @@ -801,7 +813,7 @@ import_find_extension(PyThreadState *tstate, PyObject *name, } Py_DECREF(mod); } - if (_PyState_AddModule(mod, def) < 0) { + if (_PyState_AddModule(tstate, mod, def) < 0) { PyMapping_DelItem(modules, name); return NULL; } diff --git a/Python/pystate.c b/Python/pystate.c index 0a6d035836e6e..d792380de4649 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -661,9 +661,8 @@ PyState_FindModule(struct PyModuleDef* module) } int -_PyState_AddModule(PyObject* module, struct PyModuleDef* def) +_PyState_AddModule(PyThreadState *tstate, PyObject* module, struct PyModuleDef* def) { - PyInterpreterState *state; if (!def) { assert(PyErr_Occurred()); return -1; @@ -673,37 +672,45 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def) "PyState_AddModule called on module with slots"); return -1; } - state = _PyInterpreterState_GET_UNSAFE(); - if (!state->modules_by_index) { - state->modules_by_index = PyList_New(0); - if (!state->modules_by_index) + + PyInterpreterState *interp = tstate->interp; + if (!interp->modules_by_index) { + interp->modules_by_index = PyList_New(0); + if (!interp->modules_by_index) { return -1; + } } - while (PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index) - if (PyList_Append(state->modules_by_index, Py_None) < 0) + + while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) { + if (PyList_Append(interp->modules_by_index, Py_None) < 0) { return -1; + } + } + Py_INCREF(module); - return PyList_SetItem(state->modules_by_index, + return PyList_SetItem(interp->modules_by_index, def->m_base.m_index, module); } int PyState_AddModule(PyObject* module, struct PyModuleDef* def) { - Py_ssize_t index; - PyInterpreterState *state = _PyInterpreterState_GET_UNSAFE(); if (!def) { Py_FatalError("PyState_AddModule: Module Definition is NULL"); return -1; } - index = def->m_base.m_index; - if (state->modules_by_index && - index < PyList_GET_SIZE(state->modules_by_index) && - module == PyList_GET_ITEM(state->modules_by_index, index)) { + + PyThreadState *tstate = _PyThreadState_GET(); + PyInterpreterState *interp = tstate->interp; + Py_ssize_t index = def->m_base.m_index; + if (interp->modules_by_index && + index < PyList_GET_SIZE(interp->modules_by_index) && + module == PyList_GET_ITEM(interp->modules_by_index, index)) + { Py_FatalError("PyState_AddModule: Module already added!"); return -1; } - return _PyState_AddModule(module, def); + return _PyState_AddModule(tstate, module, def); } int From webhook-mailer at python.org Fri Nov 22 13:25:00 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 18:25:00 -0000 Subject: [Python-checkins] bpo-38858: new_interpreter() reuses pycore_init_builtins() (GH-17351) Message-ID: https://github.com/python/cpython/commit/2582d46fbcf7bdf86b9cf4016850b8d155267ac6 commit: 2582d46fbcf7bdf86b9cf4016850b8d155267ac6 branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T19:24:49+01:00 summary: bpo-38858: new_interpreter() reuses pycore_init_builtins() (GH-17351) new_interpreter() now calls _PyBuiltin_Init() to create the builtins module and calls _PyImport_FixupBuiltin(), rather than using _PyImport_FindBuiltin(tstate, "builtins"). pycore_init_builtins() is now responsible to initialize intepr->builtins_copy: inline _PyImport_Init() and remove this function. files: M Doc/data/refcounts.dat M Include/internal/pycore_pylifecycle.h M Python/import.c M Python/pylifecycle.c diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index cfed1bd503118..b55e972d536fe 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -3045,8 +3045,6 @@ Py_XINCREF:PyObject*:o:+1:if o is not NULL _PyImport_Fini:void::: -_PyImport_Init:void::: - _PyObject_New:PyObject*::+1: _PyObject_New:PyTypeObject*:type:0: diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 73aa5ef1f6cab..cd3be215ff112 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -44,7 +44,6 @@ extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern int _PySys_InitMain(PyThreadState *tstate); -extern PyStatus _PyImport_Init(PyThreadState *tstate); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); diff --git a/Python/import.c b/Python/import.c index 923c6d0465d2e..045b6d0a9bf6f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -48,17 +48,6 @@ module _imp /* Initialize things */ -PyStatus -_PyImport_Init(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - interp->builtins_copy = PyDict_Copy(interp->builtins); - if (interp->builtins_copy == NULL) { - return _PyStatus_ERR("Can't backup builtins dict"); - } - return _PyStatus_OK(); -} - PyStatus _PyImportHooks_Init(PyThreadState *tstate) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index e692d75999d6b..e63fb64469de5 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -622,25 +622,36 @@ pycore_init_types(PyThreadState *tstate) static PyStatus pycore_init_builtins(PyThreadState *tstate) { - PyInterpreterState *interp = tstate->interp; - PyObject *bimod = _PyBuiltin_Init(tstate); if (bimod == NULL) { - return _PyStatus_ERR("can't initialize builtins modules"); + goto error; + } + + PyInterpreterState *interp = tstate->interp; + if (_PyImport_FixupBuiltin(bimod, "builtins", interp->modules) < 0) { + goto error; } - _PyImport_FixupBuiltin(bimod, "builtins", interp->modules); - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) { - return _PyStatus_ERR("can't initialize builtins dict"); + PyObject *builtins_dict = PyModule_GetDict(bimod); + if (builtins_dict == NULL) { + goto error; } - Py_INCREF(interp->builtins); + Py_INCREF(builtins_dict); + interp->builtins = builtins_dict; PyStatus status = _PyBuiltins_AddExceptions(bimod); if (_PyStatus_EXCEPTION(status)) { return status; } + + interp->builtins_copy = PyDict_Copy(interp->builtins); + if (interp->builtins_copy == NULL) { + goto error; + } return _PyStatus_OK(); + +error: + return _PyStatus_ERR("can't initialize builtins module"); } @@ -649,12 +660,7 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) { const PyConfig *config = &tstate->interp->config; - PyStatus status = _PyImport_Init(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyImportHooks_Init(tstate); + PyStatus status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1558,23 +1564,12 @@ new_interpreter(PyThreadState **tstate_p) goto handle_exc; } - PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins"); - if (bimod != NULL) { - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - goto handle_exc; - Py_INCREF(interp->builtins); - } - else if (_PyErr_Occurred(tstate)) { - goto handle_exc; + status = pycore_init_builtins(tstate); + if (_PyStatus_EXCEPTION(status)) { + goto done; } - if (bimod != NULL && sysmod != NULL) { - status = _PyBuiltins_AddExceptions(bimod); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - + if (sysmod != NULL) { status = _PySys_SetPreliminaryStderr(interp->sysdict); if (_PyStatus_EXCEPTION(status)) { goto done; From webhook-mailer at python.org Fri Nov 22 15:54:40 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Fri, 22 Nov 2019 20:54:40 -0000 Subject: [Python-checkins] bpo-38858: new_interpreter() uses pycore_init_import_warnings() (GH-17353) Message-ID: https://github.com/python/cpython/commit/2ec1a1b307cc893adae4662a32e1d2e94b6908e3 commit: 2ec1a1b307cc893adae4662a32e1d2e94b6908e3 branch: master author: Victor Stinner committer: GitHub date: 2019-11-22T21:54:33+01:00 summary: bpo-38858: new_interpreter() uses pycore_init_import_warnings() (GH-17353) files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index e63fb64469de5..cce4783bc12c3 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -665,15 +665,17 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) return status; } - /* Initialize _warnings. */ - if (_PyWarnings_Init() == NULL) { - return _PyStatus_ERR("can't initialize warnings"); - } + if (_Py_IsMainInterpreter(tstate)) { + /* Initialize _warnings. */ + if (_PyWarnings_Init() == NULL) { + return _PyStatus_ERR("can't initialize warnings"); + } - if (config->_install_importlib) { - status = _PyConfig_WritePathConfig(config); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (config->_install_importlib) { + status = _PyConfig_WritePathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } } @@ -1575,12 +1577,7 @@ new_interpreter(PyThreadState **tstate_p) goto done; } - status = _PyImportHooks_Init(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = init_importlib(tstate, sysmod); + status = pycore_init_import_warnings(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { goto done; } From webhook-mailer at python.org Fri Nov 22 17:09:19 2019 From: webhook-mailer at python.org (Ned Deily) Date: Fri, 22 Nov 2019 22:09:19 -0000 Subject: [Python-checkins] bpo-38804: Fix REDoS in http.cookiejar (GH-17157) (#17343) Message-ID: https://github.com/python/cpython/commit/0716056c49e9505041e30386dad9b2e788f67aaf commit: 0716056c49e9505041e30386dad9b2e788f67aaf branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Ned Deily date: 2019-11-22T17:09:10-05:00 summary: bpo-38804: Fix REDoS in http.cookiejar (GH-17157) (#17343) The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar to parse Set-Cookie headers returned by a server. Processing a response from a malicious HTTP server can lead to extreme CPU usage and execution will be blocked for a long time. The regex contained multiple overlapping \s* capture groups. Ignoring the ?-optional capture groups the regex could be simplified to \d+-\w+-\d+(\s*\s*\s*)$ Therefore, a long sequence of spaces can trigger bad performance. Matching a malicious string such as LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!") caused catastrophic backtracking. The fix removes ambiguity about which \s* should match a particular space. You can create a malicious server which responds with Set-Cookie headers to attack all python programs which access it e.g. from http.server import BaseHTTPRequestHandler, HTTPServer def make_set_cookie_value(n_spaces): spaces = " " * n_spaces expiry = f"1-c-1{spaces}!" return f"b;Expires={expiry}" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.log_request(204) self.send_response_only(204) GH- Don't bother sending Server and Date n_spaces = ( int(self.path[1:]) GH- Can GET e.g. /100 to test shorter sequences if len(self.path) > 1 else 65506 GH- Max header line length 65536 ) value = make_set_cookie_value(n_spaces) for i in range(99): GH- Not necessary, but we can have up to 100 header lines self.send_header("Set-Cookie", value) self.end_headers() if __name__ == "__main__": HTTPServer(("", 44020), Handler).serve_forever() This server returns 99 Set-Cookie headers. Each has 65506 spaces. Extracting the cookies will pretty much never complete. Vulnerable client using the example at the bottom of https://docs.python.org/3/library/http.cookiejar.html : import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) r = opener.open("http://localhost:44020/") The popular requests library was also vulnerable without any additional options (as it uses http.cookiejar by default): import requests requests.get("http://localhost:44020/") * Regression test for http.cookiejar REDoS If we regress, this test will take a very long time. * Improve performance of http.cookiejar.ISO_DATE_RE A string like "444444" + (" " * 2000) + "A" could cause poor performance due to the 2 overlapping \s* groups, although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was. (cherry picked from commit 1b779bfb8593739b11cbb988ef82a883ec9d077e) Co-authored-by: bcaller files: A Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst M Lib/http/cookiejar.py M Lib/test/test_http_cookiejar.py M Misc/ACKS diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index e46514bb35ebd..707cf0118623d 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -216,10 +216,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X | re.ASCII) + )?$""", re.X | re.ASCII) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -289,9 +293,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X | re. ASCII) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X | re. ASCII) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index 16edf34a99259..62a65cf187cb4 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -122,6 +122,13 @@ def test_http2time_garbage(self): "http2time(%s) is not None\n" "http2time(test) %s" % (test, http2time(test))) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + def test_iso2time(self): def parse_date(text): return time.gmtime(iso2time(text))[:6] @@ -179,6 +186,12 @@ def test_iso2time_garbage(self): self.assertIsNone(iso2time(test), "iso2time(%r)" % test) + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(unittest.TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index c78df75f0dcb6..31f4d517c8949 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -232,6 +232,7 @@ Zach Byrne Vedran ?a?i? Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst new file mode 100644 index 0000000000000..1f45142d9f743 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst @@ -0,0 +1 @@ +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. From webhook-mailer at python.org Fri Nov 22 17:28:48 2019 From: webhook-mailer at python.org (Ethan Furman) Date: Fri, 22 Nov 2019 22:28:48 -0000 Subject: [Python-checkins] Update CODEOWNERS (#17356) Message-ID: https://github.com/python/cpython/commit/3ae38cc181fe513abc09c8931f910eeb61bac60d commit: 3ae38cc181fe513abc09c8931f910eeb61bac60d branch: master author: Ethan Furman committer: GitHub date: 2019-11-22T14:28:41-08:00 summary: Update CODEOWNERS (#17356) Add Ethan Furman for enum, cgi, and cgitb. files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 32d21143231e4..7b415ac5c2f52 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -114,6 +114,9 @@ Include/pytime.h @pganssle @abalkin **/*ftplib @giampaolo **/*shutil @giampaolo +**/*enum* @ethanfurman +**/*cgi* @ethanfurman + # macOS /Mac/ @python/macos-team **/*osx_support* @python/macos-team From webhook-mailer at python.org Fri Nov 22 18:19:20 2019 From: webhook-mailer at python.org (Senthil Kumaran) Date: Fri, 22 Nov 2019 23:19:20 -0000 Subject: [Python-checkins] bpo-38686: fix HTTP Digest handling in request.py (#17045) Message-ID: https://github.com/python/cpython/commit/14a89c47983f2fb9e7fdf33c769e622eefd3a14a commit: 14a89c47983f2fb9e7fdf33c769e622eefd3a14a branch: master author: PypeBros committer: Senthil Kumaran date: 2019-11-22T15:19:08-08:00 summary: bpo-38686: fix HTTP Digest handling in request.py (#17045) * fix HTTP Digest handling in request.py There is a bug triggered when server replies to a request with `WWW-Authenticate: Digest` where `qop="auth,auth-int"` rather than mere `qop="auth"`. Having both `auth` and `auth-int` is legitimate according to the `qop-options` rule in ?3.2.1 of [[https://www.ietf.org/rfc/rfc2617.txt|RFC 2617]]: > qop-options = "qop" "=" <"> 1#qop-value <"> > qop-value = "auth" | "auth-int" | token > **qop-options**: [...] If present, it is a quoted string **of one or more** tokens indicating the "quality of protection" values supported by the server. The value `"auth"` indicates authentication; the value `"auth-int"` indicates authentication with integrity protection This is description confirmed by the definition of the [//n//]`#`[//m//]//rule// extended-BNF pattern defined in ?2.1 of [[https://www.ietf.org/rfc/rfc2616.txt|RFC 2616]] as 'a comma-separated list of //rule// with at least //n// and at most //m// items'. When this reply is parsed by `get_authorization`, request.py only tests for identity with `'auth'`, failing to recognize it as one of the supported modes the server announced, and claims that `"qop 'auth,auth-int' is not supported"`. * ?? Added by blurb_it. * bpo-38686 review fix: remember why. * fix trailing space in Lib/urllib/request.py Co-Authored-By: Brandt Bucher files: A Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index ebc41184f83d5..39553d809a3f1 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1136,7 +1136,9 @@ def get_authorization(self, req, chal): A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls req.selector) - if qop == 'auth': + # NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth` + # or `auth-int` to the response back. we use `auth` to send the response back. + if 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1144,7 +1146,7 @@ def get_authorization(self, req, chal): self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) - noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) + noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2)) respdig = KD(H(A1), noncebit) elif qop is None: respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) diff --git a/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst new file mode 100644 index 0000000000000..7a419ff1e3338 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst @@ -0,0 +1 @@ +Added support for multiple ``qop`` values in :class:`urllib.request.AbstractDigestAuthHandler`. \ No newline at end of file From webhook-mailer at python.org Fri Nov 22 18:36:42 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 23:36:42 -0000 Subject: [Python-checkins] bpo-38686: fix HTTP Digest handling in request.py (GH-17045) Message-ID: https://github.com/python/cpython/commit/b9e5547f5814962964c4a5bd5cd36a2af8fbf974 commit: b9e5547f5814962964c4a5bd5cd36a2af8fbf974 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T15:36:38-08:00 summary: bpo-38686: fix HTTP Digest handling in request.py (GH-17045) * fix HTTP Digest handling in request.py There is a bug triggered when server replies to a request with `WWW-Authenticate: Digest` where `qop="auth,auth-int"` rather than mere `qop="auth"`. Having both `auth` and `auth-int` is legitimate according to the `qop-options` rule in ?3.2.1 of [[https://www.ietf.org/rfc/rfc2617.txt|RFC 2617]]: > qop-options = "qop" "=" <"> 1GH-qop-value <"> > qop-value = "auth" | "auth-int" | token > **qop-options**: [...] If present, it is a quoted string **of one or more** tokens indicating the "quality of protection" values supported by the server. The value `"auth"` indicates authentication; the value `"auth-int"` indicates authentication with integrity protection This is description confirmed by the definition of the [//n//]`GH-`[//m//]//rule// extended-BNF pattern defined in ?2.1 of [[https://www.ietf.org/rfc/rfc2616.txt|RFC 2616]] as 'a comma-separated list of //rule// with at least //n// and at most //m// items'. When this reply is parsed by `get_authorization`, request.py only tests for identity with `'auth'`, failing to recognize it as one of the supported modes the server announced, and claims that `"qop 'auth,auth-int' is not supported"`. * ?? Added by blurb_it. * bpo-38686 review fix: remember why. * fix trailing space in Lib/urllib/request.py Co-Authored-By: Brandt Bucher (cherry picked from commit 14a89c47983f2fb9e7fdf33c769e622eefd3a14a) Co-authored-by: PypeBros files: A Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 92c6a5d015051..51c4759629fd1 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1144,7 +1144,9 @@ def get_authorization(self, req, chal): A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls req.selector) - if qop == 'auth': + # NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth` + # or `auth-int` to the response back. we use `auth` to send the response back. + if 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1152,7 +1154,7 @@ def get_authorization(self, req, chal): self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) - noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) + noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2)) respdig = KD(H(A1), noncebit) elif qop is None: respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) diff --git a/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst new file mode 100644 index 0000000000000..7a419ff1e3338 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst @@ -0,0 +1 @@ +Added support for multiple ``qop`` values in :class:`urllib.request.AbstractDigestAuthHandler`. \ No newline at end of file From webhook-mailer at python.org Fri Nov 22 18:38:42 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 22 Nov 2019 23:38:42 -0000 Subject: [Python-checkins] bpo-38686: fix HTTP Digest handling in request.py (GH-17045) Message-ID: https://github.com/python/cpython/commit/07432c33a0cab9d40ec71b274ec4bca5c57ca6e9 commit: 07432c33a0cab9d40ec71b274ec4bca5c57ca6e9 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-22T15:38:37-08:00 summary: bpo-38686: fix HTTP Digest handling in request.py (GH-17045) * fix HTTP Digest handling in request.py There is a bug triggered when server replies to a request with `WWW-Authenticate: Digest` where `qop="auth,auth-int"` rather than mere `qop="auth"`. Having both `auth` and `auth-int` is legitimate according to the `qop-options` rule in ?3.2.1 of [[https://www.ietf.org/rfc/rfc2617.txt|RFC 2617]]: > qop-options = "qop" "=" <"> 1GH-qop-value <"> > qop-value = "auth" | "auth-int" | token > **qop-options**: [...] If present, it is a quoted string **of one or more** tokens indicating the "quality of protection" values supported by the server. The value `"auth"` indicates authentication; the value `"auth-int"` indicates authentication with integrity protection This is description confirmed by the definition of the [//n//]`GH-`[//m//]//rule// extended-BNF pattern defined in ?2.1 of [[https://www.ietf.org/rfc/rfc2616.txt|RFC 2616]] as 'a comma-separated list of //rule// with at least //n// and at most //m// items'. When this reply is parsed by `get_authorization`, request.py only tests for identity with `'auth'`, failing to recognize it as one of the supported modes the server announced, and claims that `"qop 'auth,auth-int' is not supported"`. * ?? Added by blurb_it. * bpo-38686 review fix: remember why. * fix trailing space in Lib/urllib/request.py Co-Authored-By: Brandt Bucher (cherry picked from commit 14a89c47983f2fb9e7fdf33c769e622eefd3a14a) Co-authored-by: PypeBros files: A Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst M Lib/urllib/request.py diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 37b2548628878..1ec484ed249c6 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1143,7 +1143,9 @@ def get_authorization(self, req, chal): A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls req.selector) - if qop == 'auth': + # NOTE: As per RFC 2617, when server sends "auth,auth-int", the client could use either `auth` + # or `auth-int` to the response back. we use `auth` to send the response back. + if 'auth' in qop.split(','): if nonce == self.last_nonce: self.nonce_count += 1 else: @@ -1151,7 +1153,7 @@ def get_authorization(self, req, chal): self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) - noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) + noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, 'auth', H(A2)) respdig = KD(H(A1), noncebit) elif qop is None: respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) diff --git a/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst new file mode 100644 index 0000000000000..7a419ff1e3338 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-06-15-26-15.bpo-38686.HNFBce.rst @@ -0,0 +1 @@ +Added support for multiple ``qop`` values in :class:`urllib.request.AbstractDigestAuthHandler`. \ No newline at end of file From webhook-mailer at python.org Fri Nov 22 20:30:53 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Sat, 23 Nov 2019 01:30:53 -0000 Subject: [Python-checkins] bpo-38896: Remove PyUnicode_ClearFreeList() function (GH-17354) Message-ID: https://github.com/python/cpython/commit/d68b592dd67cb87c4fa862a8d3b3fd0a7d05e113 commit: d68b592dd67cb87c4fa862a8d3b3fd0a7d05e113 branch: master author: Victor Stinner committer: GitHub date: 2019-11-23T02:30:32+01:00 summary: bpo-38896: Remove PyUnicode_ClearFreeList() function (GH-17354) Remove PyUnicode_ClearFreeList() function: the Unicode free list has been removed in Python 3.3. files: A Misc/NEWS.d/next/C API/2019-11-22-19-43-43.bpo-38896.6wvNMJ.rst M Doc/c-api/unicode.rst M Doc/whatsnew/3.9.rst M Include/unicodeobject.h M Modules/gcmodule.c M Objects/unicodeobject.c M PC/python3.def diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 2bf4a0f56bc8a..77f123cf1f2c0 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -197,11 +197,6 @@ access internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: int PyUnicode_ClearFreeList() - - Clear the free list. Return the total number of freed items. - - .. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) Return the size of the deprecated :c:type:`Py_UNICODE` representation, in diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 281173edb895b..a3ad98d020642 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -235,6 +235,10 @@ Build and C API Changes functions: the free lists of bound method objects have been removed. (Contributed by Inada Naoki and Victor Stinner in :issue:`37340`.) +* Remove ``PyUnicode_ClearFreeList()`` function: the Unicode free list has been + removed in Python 3.3. + (Contributed by Victor Stinner in :issue:`38896`.) + Deprecated ========== diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 97d8cd12f6de5..4dea494218122 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -328,17 +328,6 @@ PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); -/* --- Free-list management ----------------------------------------------- */ - -/* Clear the free list used by the Unicode implementation. - - This can be used to release memory used for objects on the free - list back to the Python memory allocator. - -*/ - -PyAPI_FUNC(int) PyUnicode_ClearFreeList(void); - /* === Builtin Codecs ===================================================== Many of these APIs take two arguments encoding and errors. These diff --git a/Misc/NEWS.d/next/C API/2019-11-22-19-43-43.bpo-38896.6wvNMJ.rst b/Misc/NEWS.d/next/C API/2019-11-22-19-43-43.bpo-38896.6wvNMJ.rst new file mode 100644 index 0000000000000..c5e108d769312 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-11-22-19-43-43.bpo-38896.6wvNMJ.rst @@ -0,0 +1,2 @@ +Remove ``PyUnicode_ClearFreeList()`` function: the Unicode free list has +been removed in Python 3.3. diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index d232179a11ce4..64afe831c84c5 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -1031,7 +1031,6 @@ clear_freelists(void) { (void)PyFrame_ClearFreeList(); (void)PyTuple_ClearFreeList(); - (void)PyUnicode_ClearFreeList(); (void)PyFloat_ClearFreeList(); (void)PyList_ClearFreeList(); (void)PyDict_ClearFreeList(); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 89e45d01e3789..77760195b32e7 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15332,14 +15332,6 @@ _PyUnicode_Init(void) return _PyStatus_OK(); } -/* Finalize the Unicode implementation */ - -int -PyUnicode_ClearFreeList(void) -{ - return 0; -} - void PyUnicode_InternInPlace(PyObject **p) @@ -15951,7 +15943,6 @@ _PyUnicode_Fini(PyThreadState *tstate) Py_CLEAR(unicode_latin1[i]); } _PyUnicode_ClearStaticStrings(); - (void)PyUnicode_ClearFreeList(); } PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); diff --git a/PC/python3.def b/PC/python3.def index 1f355bffc9bdd..4689b777a6933 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -649,7 +649,6 @@ EXPORTS PyUnicode_AsWideChar=python39.PyUnicode_AsWideChar PyUnicode_AsWideCharString=python39.PyUnicode_AsWideCharString PyUnicode_BuildEncodingMap=python39.PyUnicode_BuildEncodingMap - PyUnicode_ClearFreeList=python39.PyUnicode_ClearFreeList PyUnicode_Compare=python39.PyUnicode_Compare PyUnicode_CompareWithASCIIString=python39.PyUnicode_CompareWithASCIIString PyUnicode_Concat=python39.PyUnicode_Concat From webhook-mailer at python.org Sat Nov 23 02:32:39 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sat, 23 Nov 2019 07:32:39 -0000 Subject: [Python-checkins] bpo-38899: virtual environment activation for fish should use `source` (GH-17359) Message-ID: https://github.com/python/cpython/commit/84b1ff65609c5910b4f838adbe1ead83baae7dbf commit: 84b1ff65609c5910b4f838adbe1ead83baae7dbf branch: master author: Brett Cannon <54418+brettcannon at users.noreply.github.com> committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-22T23:32:27-08:00 summary: bpo-38899: virtual environment activation for fish should use `source` (GH-17359) The previously documented use of `.` is considered deprecated (https://fishshell.com/docs/current/commands.html#source). https://bugs.python.org/issue38899 Automerge-Triggered-By: @brettcannon files: A Misc/NEWS.d/next/Documentation/2019-11-22-15-57-29.bpo-38899.4aYPW2.rst M Doc/using/venv-create.inc M Lib/venv/scripts/posix/activate.fish diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index cf5af437d6aee..6c6617dc158f7 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -104,7 +104,7 @@ directory containing the virtual environment): +=============+=================+=========================================+ | POSIX | bash/zsh | $ source /bin/activate | +-------------+-----------------+-----------------------------------------+ -| | fish | $ . /bin/activate.fish | +| | fish | $ source /bin/activate.fish | +-------------+-----------------+-----------------------------------------+ | | csh/tcsh | $ source /bin/activate.csh | +-------------+-----------------+-----------------------------------------+ diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index 777d51cb69b0c..d213b9060a687 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -1,5 +1,5 @@ -# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org); -# you cannot run it directly. +# This file must be used with "source /bin/activate.fish" *from fish* +# (http://fishshell.org); you cannot run it directly. function deactivate -d "Exit virtualenv and return to normal shell environment" # reset old environment variables diff --git a/Misc/NEWS.d/next/Documentation/2019-11-22-15-57-29.bpo-38899.4aYPW2.rst b/Misc/NEWS.d/next/Documentation/2019-11-22-15-57-29.bpo-38899.4aYPW2.rst new file mode 100644 index 0000000000000..4ee178bfb1b3a --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-22-15-57-29.bpo-38899.4aYPW2.rst @@ -0,0 +1,3 @@ +Update documentation to state that to activate virtual environments under +fish one should use `source`, not `.` as documented at +https://fishshell.com/docs/current/commands.html#source. From webhook-mailer at python.org Sat Nov 23 05:22:24 2019 From: webhook-mailer at python.org (Raymond Hettinger) Date: Sat, 23 Nov 2019 10:22:24 -0000 Subject: [Python-checkins] bpo-38881: choices() raises ValueError when all weights are zero (GH-17362) Message-ID: https://github.com/python/cpython/commit/041d8b48a2e59fa642b2c5124d78086baf74e339 commit: 041d8b48a2e59fa642b2c5124d78086baf74e339 branch: master author: Raymond Hettinger committer: GitHub date: 2019-11-23T02:22:13-08:00 summary: bpo-38881: choices() raises ValueError when all weights are zero (GH-17362) files: A Misc/NEWS.d/next/Library/2019-11-22-20-03-46.bpo-38881.7HV1Q0.rst M Doc/library/random.rst M Lib/random.py M Lib/test/test_random.py diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 1bd1856937be5..933da3f8fcf65 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -165,8 +165,9 @@ Functions for sequences The *weights* or *cum_weights* can use any numeric type that interoperates with the :class:`float` values returned by :func:`random` (that includes - integers, floats, and fractions but excludes decimals). Weights are - assumed to be non-negative. + integers, floats, and fractions but excludes decimals). Behavior is + undefined if any weight is negative. A :exc:`ValueError` is raised if all + weights are zero. For a given seed, the :func:`choices` function with equal weighting typically produces a different sequence than repeated calls to @@ -177,6 +178,9 @@ Functions for sequences .. versionadded:: 3.6 + .. versionchanged:: 3.9 + Raises a :exc:`ValueError` if all weights are zero. + .. function:: shuffle(x[, random]) diff --git a/Lib/random.py b/Lib/random.py index be4401c554d7e..e24737d4508a8 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -413,8 +413,10 @@ def choices(self, population, weights=None, *, cum_weights=None, k=1): raise TypeError('Cannot specify both weights and cumulative weights') if len(cum_weights) != n: raise ValueError('The number of weights does not match the population') - bisect = _bisect total = cum_weights[-1] + 0.0 # convert to float + if total <= 0.0: + raise ValueError('Total of weights must be greater than zero') + bisect = _bisect hi = n - 1 return [population[bisect(cum_weights, random() * total, 0, hi)] for i in _repeat(None, k)] diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index f59c5652b5dda..2c8c8e885452a 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -241,6 +241,11 @@ def test_choices_subnormal(self): choices = self.gen.choices choices(population=[1, 2], weights=[1e-323, 1e-323], k=5000) + def test_choices_with_all_zero_weights(self): + # See issue #38881 + with self.assertRaises(ValueError): + self.gen.choices('AB', [0.0, 0.0]) + def test_gauss(self): # Ensure that the seed() method initializes all the hidden state. In # particular, through 2.2.1 it failed to reset a piece of state used diff --git a/Misc/NEWS.d/next/Library/2019-11-22-20-03-46.bpo-38881.7HV1Q0.rst b/Misc/NEWS.d/next/Library/2019-11-22-20-03-46.bpo-38881.7HV1Q0.rst new file mode 100644 index 0000000000000..9f4a27db4524f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-22-20-03-46.bpo-38881.7HV1Q0.rst @@ -0,0 +1 @@ +random.choices() now raises a ValueError when all the weights are zero. From webhook-mailer at python.org Sun Nov 24 05:49:16 2019 From: webhook-mailer at python.org (Ivan Levkivskyi) Date: Sun, 24 Nov 2019 10:49:16 -0000 Subject: [Python-checkins] Better runtime TypedDict (GH-17214) Message-ID: https://github.com/python/cpython/commit/665ad3dfa9993b9a4000b097ddead4e292590e8c commit: 665ad3dfa9993b9a4000b097ddead4e292590e8c branch: master author: Zac Hatfield-Dodds committer: Ivan Levkivskyi date: 2019-11-24T10:48:48Z summary: Better runtime TypedDict (GH-17214) This patch enables downstream projects inspecting a TypedDict subclass at runtime to tell which keys are optional. This is essential for generating test data with Hypothesis or validating inputs with typeguard or pydantic. files: A Misc/NEWS.d/next/Library/2019-11-18-17-08-23.bpo-38834.abcdef.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index ccd617c1fdff0..5b4916f9c3260 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3741,6 +3741,13 @@ def test_total(self): self.assertEqual(Options(log_level=2), {'log_level': 2}) self.assertEqual(Options.__total__, False) + def test_optional_keys(self): + class Point2Dor3D(Point2D, total=False): + z: int + + assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y']) + assert Point2Dor3D.__optional_keys__ == frozenset(['z']) + class IOTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 5523ee01e1f99..7de3e346eaa79 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1715,9 +1715,20 @@ def __new__(cls, name, bases, ns, total=True): anns = ns.get('__annotations__', {}) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" anns = {n: _type_check(tp, msg) for n, tp in anns.items()} + required = set(anns if total else ()) + optional = set(() if total else anns) + for base in bases: - anns.update(base.__dict__.get('__annotations__', {})) + base_anns = base.__dict__.get('__annotations__', {}) + anns.update(base_anns) + if getattr(base, '__total__', True): + required.update(base_anns) + else: + optional.update(base_anns) + tp_dict.__annotations__ = anns + tp_dict.__required_keys__ = frozenset(required) + tp_dict.__optional_keys__ = frozenset(optional) if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total return tp_dict @@ -1744,8 +1755,9 @@ class Point2D(TypedDict): assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - The type info can be accessed via Point2D.__annotations__. TypedDict - supports two additional equivalent forms:: + The type info can be accessed via the Point2D.__annotations__ dict, and + the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. + TypedDict supports two additional equivalent forms:: Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) diff --git a/Misc/NEWS.d/next/Library/2019-11-18-17-08-23.bpo-38834.abcdef.rst b/Misc/NEWS.d/next/Library/2019-11-18-17-08-23.bpo-38834.abcdef.rst new file mode 100644 index 0000000000000..af108b1efbc3b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-18-17-08-23.bpo-38834.abcdef.rst @@ -0,0 +1,3 @@ +:class:`typing.TypedDict` subclasses now track which keys are optional using +the ``__required_keys__`` and ``__optional_keys__`` attributes, to enable +runtime validation by downstream projects. Patch by Zac Hatfield-Dodds. From webhook-mailer at python.org Sun Nov 24 10:49:27 2019 From: webhook-mailer at python.org (Victor Stinner) Date: Sun, 24 Nov 2019 15:49:27 -0000 Subject: [Python-checkins] bpo-38804: Fix REDoS in http.cookiejar (GH-17157) (GH-17345) Message-ID: https://github.com/python/cpython/commit/e6499033032d5b647e43a3b49da0c1c64b151743 commit: e6499033032d5b647e43a3b49da0c1c64b151743 branch: 2.7 author: Victor Stinner committer: GitHub date: 2019-11-24T16:49:23+01:00 summary: bpo-38804: Fix REDoS in http.cookiejar (GH-17157) (GH-17345) The regex http.cookiejar.LOOSE_HTTP_DATE_RE was vulnerable to regular expression denial of service (REDoS). LOOSE_HTTP_DATE_RE.match is called when using http.cookiejar.CookieJar to parse Set-Cookie headers returned by a server. Processing a response from a malicious HTTP server can lead to extreme CPU usage and execution will be blocked for a long time. The regex contained multiple overlapping \s* capture groups. Ignoring the ?-optional capture groups the regex could be simplified to \d+-\w+-\d+(\s*\s*\s*)$ Therefore, a long sequence of spaces can trigger bad performance. Matching a malicious string such as LOOSE_HTTP_DATE_RE.match("1-c-1" + (" " * 2000) + "!") caused catastrophic backtracking. The fix removes ambiguity about which \s* should match a particular space. You can create a malicious server which responds with Set-Cookie headers to attack all python programs which access it e.g. from http.server import BaseHTTPRequestHandler, HTTPServer def make_set_cookie_value(n_spaces): spaces = " " * n_spaces expiry = f"1-c-1{spaces}!" return f"b;Expires={expiry}" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.log_request(204) self.send_response_only(204) # Don't bother sending Server and Date n_spaces = ( int(self.path[1:]) # Can GET e.g. /100 to test shorter sequences if len(self.path) > 1 else 65506 # Max header line length 65536 ) value = make_set_cookie_value(n_spaces) for i in range(99): # Not necessary, but we can have up to 100 header lines self.send_header("Set-Cookie", value) self.end_headers() if __name__ == "__main__": HTTPServer(("", 44020), Handler).serve_forever() This server returns 99 Set-Cookie headers. Each has 65506 spaces. Extracting the cookies will pretty much never complete. Vulnerable client using the example at the bottom of https://docs.python.org/3/library/http.cookiejar.html : import http.cookiejar, urllib.request cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) r = opener.open("http://localhost:44020/") The popular requests library was also vulnerable without any additional options (as it uses http.cookiejar by default): import requests requests.get("http://localhost:44020/") * Regression test for http.cookiejar REDoS If we regress, this test will take a very long time. * Improve performance of http.cookiejar.ISO_DATE_RE A string like "444444" + (" " * 2000) + "A" could cause poor performance due to the 2 overlapping \s* groups, although this is not as serious as the REDoS in LOOSE_HTTP_DATE_RE was. (cherry picked from commit 1b779bfb8593739b11cbb988ef82a883ec9d077e) files: A Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst M Lib/cookielib.py M Lib/test/test_cookielib.py M Misc/ACKS diff --git a/Lib/cookielib.py b/Lib/cookielib.py index 1d56d3fe4c0a2..e76d09d8a500d 100644 --- a/Lib/cookielib.py +++ b/Lib/cookielib.py @@ -205,10 +205,14 @@ def _str2time(day, mon, yr, hr, min, sec, tz): (?::(\d\d))? # optional seconds )? # optional clock \s* - ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + (?: + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+) # timezone + \s* + )? + (?: + \(\w+\) # ASCII representation of timezone in parens. \s* - (?:\(\w+\))? # ASCII representation of timezone in parens. - \s*$""", re.X) + )?$""", re.X) def http2time(text): """Returns time in seconds since epoch of time represented by a string. @@ -266,7 +270,7 @@ def http2time(text): return _str2time(day, mon, yr, hr, min, sec, tz) ISO_DATE_RE = re.compile( - """^ + r"""^ (\d{4}) # year [-\/]? (\d\d?) # numerical month @@ -278,9 +282,11 @@ def http2time(text): (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) )? # optional clock \s* - ([-+]?\d\d?:?(:?\d\d)? - |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) - \s*$""", re.X) + (?: + ([-+]?\d\d?:?(:?\d\d)? + |Z|z) # timezone (Z is "zero meridian", i.e. GMT) + \s* + )?$""", re.X) def iso2time(text): """ As for http2time, but parses the ISO 8601 formats: diff --git a/Lib/test/test_cookielib.py b/Lib/test/test_cookielib.py index a93bbfb640b6a..f3711b966e572 100644 --- a/Lib/test/test_cookielib.py +++ b/Lib/test/test_cookielib.py @@ -6,7 +6,7 @@ import re import time -from cookielib import http2time, time2isoz, time2netscape +from cookielib import http2time, time2isoz, iso2time, time2netscape from unittest import TestCase from test import test_support @@ -117,6 +117,19 @@ def test_http2time_garbage(self): "http2time(test) %s" % (test, http2time(test)) ) + def test_http2time_redos_regression_actually_completes(self): + # LOOSE_HTTP_DATE_RE was vulnerable to malicious input which caused catastrophic backtracking (REDoS). + # If we regress to cubic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + http2time("01 Jan 1970{}00:00:00 GMT!".format(" " * 10 ** 5)) + http2time("01 Jan 1970 00:00:00{}GMT!".format(" " * 10 ** 5)) + + def test_iso2time_performance_regression(self): + # If ISO_DATE_RE regresses to quadratic complexity, this test will take a very long time to succeed. + # If fixed, it should complete within a fraction of a second. + iso2time('1994-02-03{}14:15:29 -0100!'.format(' '*10**6)) + iso2time('1994-02-03 14:15:29{}-0100!'.format(' '*10**6)) + class HeaderTests(TestCase): diff --git a/Misc/ACKS b/Misc/ACKS index eba64ae02586c..fd28ce7fe23ec 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -210,6 +210,7 @@ Ralph Butler Zach Byrne Nicolas Cadou Jp Calderone +Ben Caller Arnaud Calmettes Daniel Calvelo Tony Campbell diff --git a/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst new file mode 100644 index 0000000000000..1f45142d9f743 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-11-15-00-54-42.bpo-38804.vjbM8V.rst @@ -0,0 +1 @@ +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. From webhook-mailer at python.org Sun Nov 24 11:46:22 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Sun, 24 Nov 2019 16:46:22 -0000 Subject: [Python-checkins] Remove unnecessary variable definition (GH-17368) Message-ID: https://github.com/python/cpython/commit/e407646b741db6851789963e525a1f5daad0a336 commit: e407646b741db6851789963e525a1f5daad0a336 branch: master author: Batuhan Ta?kaya <47358913+isidentical at users.noreply.github.com> committer: Pablo Galindo date: 2019-11-24T16:46:18Z summary: Remove unnecessary variable definition (GH-17368) files: M Lib/inspect.py diff --git a/Lib/inspect.py b/Lib/inspect.py index 3ff395ca33377..608ca9551160e 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1136,7 +1136,6 @@ def getfullargspec(func): varkw = None posonlyargs = [] kwonlyargs = [] - defaults = () annotations = {} defaults = () kwdefaults = {} From webhook-mailer at python.org Sun Nov 24 14:15:12 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Sun, 24 Nov 2019 19:15:12 -0000 Subject: [Python-checkins] bpo-38876: Raise pickle.UnpicklingError when loading an item from memo for invalid input (GH-17335) Message-ID: https://github.com/python/cpython/commit/6f03b236c17c96bc9f8a004ffa7e7ae0542e9cac commit: 6f03b236c17c96bc9f8a004ffa7e7ae0542e9cac branch: master author: Claudiu Popa committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-24T11:15:08-08:00 summary: bpo-38876: Raise pickle.UnpicklingError when loading an item from memo for invalid input (GH-17335) The previous code was raising a `KeyError` for both the Python and C implementation. This was caused by the specified index of an invalid input which did not exist in the memo structure, where the pickle stores what objects it has seen. The malformed input would have caused either a `BINGET` or `LONG_BINGET` load from the memo, leading to a `KeyError` as the determined index was bogus. https://bugs.python.org/issue38876 https://bugs.python.org/issue38876 files: A Misc/NEWS.d/next/Library/2019-11-22-10-58-58.bpo-38876.qqy1Vp.rst M Lib/pickle.py M Lib/test/pickletester.py M Modules/_pickle.c diff --git a/Lib/pickle.py b/Lib/pickle.py index 71aa57d500ecc..01d41422aa4a6 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1604,17 +1604,29 @@ def load_dup(self): def load_get(self): i = int(self.readline()[:-1]) - self.append(self.memo[i]) + try: + self.append(self.memo[i]) + except KeyError: + msg = f'Memo value not found at index {i}' + raise UnpicklingError(msg) from None dispatch[GET[0]] = load_get def load_binget(self): i = self.read(1)[0] - self.append(self.memo[i]) + try: + self.append(self.memo[i]) + except KeyError as exc: + msg = f'Memo value not found at index {i}' + raise UnpicklingError(msg) from None dispatch[BINGET[0]] = load_binget def load_long_binget(self): i, = unpack('UnpicklingError, "Memo value not found at index %ld", idx); + } Py_DECREF(key); return -1; } @@ -6201,7 +6203,8 @@ load_binget(UnpicklerObject *self) if (value == NULL) { PyObject *key = PyLong_FromSsize_t(idx); if (key != NULL) { - PyErr_SetObject(PyExc_KeyError, key); + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); Py_DECREF(key); } return -1; @@ -6227,7 +6230,8 @@ load_long_binget(UnpicklerObject *self) if (value == NULL) { PyObject *key = PyLong_FromSsize_t(idx); if (key != NULL) { - PyErr_SetObject(PyExc_KeyError, key); + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); Py_DECREF(key); } return -1; From webhook-mailer at python.org Sun Nov 24 16:29:33 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Sun, 24 Nov 2019 21:29:33 -0000 Subject: [Python-checkins] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) Message-ID: https://github.com/python/cpython/commit/6bf644ec82f14cceae68278dc35bafb00875efae commit: 6bf644ec82f14cceae68278dc35bafb00875efae branch: master author: Terry Jan Reedy committer: GitHub date: 2019-11-24T16:29:29-05:00 summary: bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) Extra newlines are removed at the end of non-shell files. If the file only has newlines after stripping other trailing whitespace, all are removed, as is done by patchcheck.py. files: A Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/format.py M Lib/idlelib/help.html M Lib/idlelib/idle_test/mock_idle.py M Lib/idlelib/idle_test/test_format.py diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c22b182..273b5830e4293 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,8 @@ Format Paragraph Strip trailing whitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, - including lines within multiline strings. + including lines within multiline strings. Except for Shell windows, + remove extra newlines at the end of the file. .. index:: single: Run script diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index c6aa00d0d54b3..5eb77398d95e6 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 2b0980565734a..4b57a182c9a49 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,6 +408,16 @@ def do_rstrip(self, event=None): if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + if (text.get('end-2c') == '\n' # File ends with at least 1 newline; + and not hasattr(self.editwin, 'interp')): # & is not Shell. + # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop if file empty. + and text.get('end-3c') == '\n'): + text.delete('end-3c') + # Because tk indexes are slice indexes and never raise, + # a file with only newlines will be emptied. + # patchcheck.py does the same. + undo.undo_block_stop() diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f2453baf6..09dc4c57bcdc0 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a0 documentation + IDLE — Python 3.9.0a1 documentation @@ -17,14 +17,14 @@ - + @@ -62,7 +62,7 @@

Navigation

next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,8 @@

    Edit menu (Shell and Editor)Table of Contents

    Previous topic

    -

    tkinter.scrolledtext ? Scrolled Text Widget

    +

    tkinter.tix ? Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +920,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +960,11 @@

    Navigation



    - Last updated on Sep 01, 2019. + Last updated on Nov 24, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52fd511f..71fa480ce4d05 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ def __call__(self, *args, **kwds): class Editor: '''Minimally imitate editor.EditorWindow class. ''' - def __init__(self, flist=None, filename=None, key=None, root=None): - self.text = Text() + def __init__(self, flist=None, filename=None, key=None, root=None, + text=None): # Allow real Text with mock Editor. + self.text = text or Text() self.undo = UndoDelegator() def get_selection_indices(self): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 20b5970f4982d..a79bb515089e7 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -611,37 +611,33 @@ def test_change_indentwidth(self, askinteger): class RstripTest(unittest.TestCase): - def test_rstrip_line(self): - editor = MockEditor() - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip - eq = self.assertEqual + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.editor = MockEditor(text=cls.text) + cls.do_rstrip = ft.Rstrip(cls.editor).do_rstrip + + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' ') - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' \n') - do_rstrip() - eq(text.get('1.0', 'insert'), '\n') - - def test_rstrip_multiple(self): - editor = MockEditor() - # Comment above, uncomment 3 below to test with real Editor & Text. - #from idlelib.editor import EditorWindow as Editor - #from tkinter import Tk - #editor = Editor(root=Tk()) - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip + def tearDown(self): + self.text.delete('1.0', 'end-1c') + def test_rstrip_lines(self): original = ( "Line with an ending tab \n" "Line ending in 5 spaces \n" "Linewithnospaces\n" " indented line\n" " indented line with trailing space \n" - " ") + " \n") stripped = ( "Line with an ending tab\n" "Line ending in 5 spaces\n" @@ -649,9 +645,23 @@ def test_rstrip_multiple(self): " indented line\n" " indented line with trailing space\n") - text.insert('1.0', original) - do_rstrip() - self.assertEqual(text.get('1.0', 'insert'), stripped) + self.text.insert('1.0', original) + self.do_rstrip() + self.assertEqual(self.text.get('1.0', 'insert'), stripped) + + def test_rstrip_end(self): + text = self.text + for code in ('', '\n', '\n\n\n'): + with self.subTest(code=code): + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for code in ('a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(code=code): + text.delete('1.0', 'end-1c') + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst new file mode 100644 index 0000000000000..14bab9e854bdc --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst @@ -0,0 +1,2 @@ +'Strip Trailing Whitespace' on the Format menu removes extra newlines +at the end of non-shell files. From webhook-mailer at python.org Sun Nov 24 18:02:47 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Sun, 24 Nov 2019 23:02:47 -0000 Subject: [Python-checkins] bpo-38870: Expose a function to unparse an ast object in the ast module (GH-17302) Message-ID: https://github.com/python/cpython/commit/27fc3b6f3fc49a36d3f962caac5c5495696d12ed commit: 27fc3b6f3fc49a36d3f962caac5c5495696d12ed branch: master author: Pablo Galindo committer: GitHub date: 2019-11-24T23:02:40Z summary: bpo-38870: Expose a function to unparse an ast object in the ast module (GH-17302) Add ast.unparse() as a function in the ast module that can be used to unparse an ast.AST object and produce a string with code that would produce an equivalent ast.AST object when parsed. files: A Lib/test/test_unparse.py A Misc/NEWS.d/next/Library/2019-11-20-22-43-48.bpo-38870.rLVZEv.rst D Lib/test/test_tools/test_unparse.py D Tools/parser/unparse.py M Doc/library/ast.rst M Doc/whatsnew/3.9.rst M Lib/ast.py diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index b468f4235df30..a7e0729b902d2 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -161,6 +161,19 @@ and classes for traversing abstract syntax trees: Added ``type_comments``, ``mode='func_type'`` and ``feature_version``. +.. function:: unparse(ast_obj) + + Unparse an :class:`ast.AST` object and generate a string with code + that would produce an equivalent :class:`ast.AST` object if parsed + back with :func:`ast.parse`. + + .. warning:: + The produced code string will not necesarily be equal to the original + code that generated the :class:`ast.AST` object. + + .. versionadded:: 3.9 + + .. function:: literal_eval(node_or_string) Safely evaluate an expression node or a string containing a Python literal or diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index a3ad98d020642..9af5259de95dd 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -121,6 +121,11 @@ Added the *indent* option to :func:`~ast.dump` which allows it to produce a multiline indented output. (Contributed by Serhiy Storchaka in :issue:`37995`.) +Added the :func:`ast.unparse` as a function in the :mod:`ast` module that can +be used to unparse an :class:`ast.AST` object and produce a string with code +that would produce an equivalent :class:`ast.AST` object when parsed. +(Contributed by Pablo Galindo and Batuhan Taskaya in :issue:`38870`.) + asyncio ------- diff --git a/Lib/ast.py b/Lib/ast.py index 720dd48a761b6..97914ebc66858 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -24,7 +24,9 @@ :copyright: Copyright 2008 by Armin Ronacher. :license: Python License. """ +import sys from _ast import * +from contextlib import contextmanager def parse(source, filename='', mode='exec', *, @@ -551,6 +553,697 @@ def __new__(cls, *args, **kwargs): type(...): 'Ellipsis', } +# Large float and imaginary literals get turned into infinities in the AST. +# We unparse those infinities to INFSTR. +_INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) + +class _Unparser(NodeVisitor): + """Methods in this class recursively traverse an AST and + output source code for the abstract syntax; original formatting + is disregarded.""" + + def __init__(self): + self._source = [] + self._buffer = [] + self._indent = 0 + + def interleave(self, inter, f, seq): + """Call f on each item in seq, calling inter() in between.""" + seq = iter(seq) + try: + f(next(seq)) + except StopIteration: + pass + else: + for x in seq: + inter() + f(x) + + def fill(self, text=""): + """Indent a piece of text and append it, according to the current + indentation level""" + self.write("\n" + " " * self._indent + text) + + def write(self, text): + """Append a piece of text""" + self._source.append(text) + + def buffer_writer(self, text): + self._buffer.append(text) + + @property + def buffer(self): + value = "".join(self._buffer) + self._buffer.clear() + return value + + @contextmanager + def block(self): + """A context manager for preparing the source for blocks. It adds + the character':', increases the indentation on enter and decreases + the indentation on exit.""" + self.write(":") + self._indent += 1 + yield + self._indent -= 1 + + def traverse(self, node): + if isinstance(node, list): + for item in node: + self.traverse(item) + else: + super().visit(node) + + def visit(self, node): + """Outputs a source code string that, if converted back to an ast + (using ast.parse) will generate an AST equivalent to *node*""" + self._source = [] + self.traverse(node) + return "".join(self._source) + + def visit_Module(self, node): + for subnode in node.body: + self.traverse(subnode) + + def visit_Expr(self, node): + self.fill() + self.traverse(node.value) + + def visit_NamedExpr(self, node): + self.write("(") + self.traverse(node.target) + self.write(" := ") + self.traverse(node.value) + self.write(")") + + def visit_Import(self, node): + self.fill("import ") + self.interleave(lambda: self.write(", "), self.traverse, node.names) + + def visit_ImportFrom(self, node): + self.fill("from ") + self.write("." * node.level) + if node.module: + self.write(node.module) + self.write(" import ") + self.interleave(lambda: self.write(", "), self.traverse, node.names) + + def visit_Assign(self, node): + self.fill() + for target in node.targets: + self.traverse(target) + self.write(" = ") + self.traverse(node.value) + + def visit_AugAssign(self, node): + self.fill() + self.traverse(node.target) + self.write(" " + self.binop[node.op.__class__.__name__] + "= ") + self.traverse(node.value) + + def visit_AnnAssign(self, node): + self.fill() + if not node.simple and isinstance(node.target, Name): + self.write("(") + self.traverse(node.target) + if not node.simple and isinstance(node.target, Name): + self.write(")") + self.write(": ") + self.traverse(node.annotation) + if node.value: + self.write(" = ") + self.traverse(node.value) + + def visit_Return(self, node): + self.fill("return") + if node.value: + self.write(" ") + self.traverse(node.value) + + def visit_Pass(self, node): + self.fill("pass") + + def visit_Break(self, node): + self.fill("break") + + def visit_Continue(self, node): + self.fill("continue") + + def visit_Delete(self, node): + self.fill("del ") + self.interleave(lambda: self.write(", "), self.traverse, node.targets) + + def visit_Assert(self, node): + self.fill("assert ") + self.traverse(node.test) + if node.msg: + self.write(", ") + self.traverse(node.msg) + + def visit_Global(self, node): + self.fill("global ") + self.interleave(lambda: self.write(", "), self.write, node.names) + + def visit_Nonlocal(self, node): + self.fill("nonlocal ") + self.interleave(lambda: self.write(", "), self.write, node.names) + + def visit_Await(self, node): + self.write("(") + self.write("await") + if node.value: + self.write(" ") + self.traverse(node.value) + self.write(")") + + def visit_Yield(self, node): + self.write("(") + self.write("yield") + if node.value: + self.write(" ") + self.traverse(node.value) + self.write(")") + + def visit_YieldFrom(self, node): + self.write("(") + self.write("yield from") + if node.value: + self.write(" ") + self.traverse(node.value) + self.write(")") + + def visit_Raise(self, node): + self.fill("raise") + if not node.exc: + if node.cause: + raise ValueError(f"Node can't use cause without an exception.") + return + self.write(" ") + self.traverse(node.exc) + if node.cause: + self.write(" from ") + self.traverse(node.cause) + + def visit_Try(self, node): + self.fill("try") + with self.block(): + self.traverse(node.body) + for ex in node.handlers: + self.traverse(ex) + if node.orelse: + self.fill("else") + with self.block(): + self.traverse(node.orelse) + if node.finalbody: + self.fill("finally") + with self.block(): + self.traverse(node.finalbody) + + def visit_ExceptHandler(self, node): + self.fill("except") + if node.type: + self.write(" ") + self.traverse(node.type) + if node.name: + self.write(" as ") + self.write(node.name) + with self.block(): + self.traverse(node.body) + + def visit_ClassDef(self, node): + self.write("\n") + for deco in node.decorator_list: + self.fill("@") + self.traverse(deco) + self.fill("class " + node.name) + self.write("(") + comma = False + for e in node.bases: + if comma: + self.write(", ") + else: + comma = True + self.traverse(e) + for e in node.keywords: + if comma: + self.write(", ") + else: + comma = True + self.traverse(e) + self.write(")") + + with self.block(): + self.traverse(node.body) + + def visit_FunctionDef(self, node): + self.__FunctionDef_helper(node, "def") + + def visit_AsyncFunctionDef(self, node): + self.__FunctionDef_helper(node, "async def") + + def __FunctionDef_helper(self, node, fill_suffix): + self.write("\n") + for deco in node.decorator_list: + self.fill("@") + self.traverse(deco) + def_str = fill_suffix + " " + node.name + "(" + self.fill(def_str) + self.traverse(node.args) + self.write(")") + if node.returns: + self.write(" -> ") + self.traverse(node.returns) + with self.block(): + self.traverse(node.body) + + def visit_For(self, node): + self.__For_helper("for ", node) + + def visit_AsyncFor(self, node): + self.__For_helper("async for ", node) + + def __For_helper(self, fill, node): + self.fill(fill) + self.traverse(node.target) + self.write(" in ") + self.traverse(node.iter) + with self.block(): + self.traverse(node.body) + if node.orelse: + self.fill("else") + with self.block(): + self.traverse(node.orelse) + + def visit_If(self, node): + self.fill("if ") + self.traverse(node.test) + with self.block(): + self.traverse(node.body) + # collapse nested ifs into equivalent elifs. + while node.orelse and len(node.orelse) == 1 and isinstance(node.orelse[0], If): + node = node.orelse[0] + self.fill("elif ") + self.traverse(node.test) + with self.block(): + self.traverse(node.body) + # final else + if node.orelse: + self.fill("else") + with self.block(): + self.traverse(node.orelse) + + def visit_While(self, node): + self.fill("while ") + self.traverse(node.test) + with self.block(): + self.traverse(node.body) + if node.orelse: + self.fill("else") + with self.block(): + self.traverse(node.orelse) + + def visit_With(self, node): + self.fill("with ") + self.interleave(lambda: self.write(", "), self.traverse, node.items) + with self.block(): + self.traverse(node.body) + + def visit_AsyncWith(self, node): + self.fill("async with ") + self.interleave(lambda: self.write(", "), self.traverse, node.items) + with self.block(): + self.traverse(node.body) + + def visit_JoinedStr(self, node): + self.write("f") + self._fstring_JoinedStr(node, self.buffer_writer) + self.write(repr(self.buffer)) + + def visit_FormattedValue(self, node): + self.write("f") + self._fstring_FormattedValue(node, self.buffer_writer) + self.write(repr(self.buffer)) + + def _fstring_JoinedStr(self, node, write): + for value in node.values: + meth = getattr(self, "_fstring_" + type(value).__name__) + meth(value, write) + + def _fstring_Constant(self, node, write): + if not isinstance(node.value, str): + raise ValueError("Constants inside JoinedStr should be a string.") + value = node.value.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_FormattedValue(self, node, write): + write("{") + expr = type(self)().visit(node.value).rstrip("\n") + if expr.startswith("{"): + write(" ") # Separate pair of opening brackets as "{ {" + write(expr) + if node.conversion != -1: + conversion = chr(node.conversion) + if conversion not in "sra": + raise ValueError("Unknown f-string conversion.") + write(f"!{conversion}") + if node.format_spec: + write(":") + meth = getattr(self, "_fstring_" + type(node.format_spec).__name__) + meth(node.format_spec, write) + write("}") + + def visit_Name(self, node): + self.write(node.id) + + def _write_constant(self, value): + if isinstance(value, (float, complex)): + # Substitute overflowing decimal literal for AST infinities. + self.write(repr(value).replace("inf", _INFSTR)) + else: + self.write(repr(value)) + + def visit_Constant(self, node): + value = node.value + if isinstance(value, tuple): + self.write("(") + if len(value) == 1: + self._write_constant(value[0]) + self.write(",") + else: + self.interleave(lambda: self.write(", "), self._write_constant, value) + self.write(")") + elif value is ...: + self.write("...") + else: + if node.kind == "u": + self.write("u") + self._write_constant(node.value) + + def visit_List(self, node): + self.write("[") + self.interleave(lambda: self.write(", "), self.traverse, node.elts) + self.write("]") + + def visit_ListComp(self, node): + self.write("[") + self.traverse(node.elt) + for gen in node.generators: + self.traverse(gen) + self.write("]") + + def visit_GeneratorExp(self, node): + self.write("(") + self.traverse(node.elt) + for gen in node.generators: + self.traverse(gen) + self.write(")") + + def visit_SetComp(self, node): + self.write("{") + self.traverse(node.elt) + for gen in node.generators: + self.traverse(gen) + self.write("}") + + def visit_DictComp(self, node): + self.write("{") + self.traverse(node.key) + self.write(": ") + self.traverse(node.value) + for gen in node.generators: + self.traverse(gen) + self.write("}") + + def visit_comprehension(self, node): + if node.is_async: + self.write(" async for ") + else: + self.write(" for ") + self.traverse(node.target) + self.write(" in ") + self.traverse(node.iter) + for if_clause in node.ifs: + self.write(" if ") + self.traverse(if_clause) + + def visit_IfExp(self, node): + self.write("(") + self.traverse(node.body) + self.write(" if ") + self.traverse(node.test) + self.write(" else ") + self.traverse(node.orelse) + self.write(")") + + def visit_Set(self, node): + if not node.elts: + raise ValueError("Set node should has at least one item") + self.write("{") + self.interleave(lambda: self.write(", "), self.traverse, node.elts) + self.write("}") + + def visit_Dict(self, node): + self.write("{") + + def write_key_value_pair(k, v): + self.traverse(k) + self.write(": ") + self.traverse(v) + + def write_item(item): + k, v = item + if k is None: + # for dictionary unpacking operator in dicts {**{'y': 2}} + # see PEP 448 for details + self.write("**") + self.traverse(v) + else: + write_key_value_pair(k, v) + + self.interleave( + lambda: self.write(", "), write_item, zip(node.keys, node.values) + ) + self.write("}") + + def visit_Tuple(self, node): + self.write("(") + if len(node.elts) == 1: + elt = node.elts[0] + self.traverse(elt) + self.write(",") + else: + self.interleave(lambda: self.write(", "), self.traverse, node.elts) + self.write(")") + + unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} + + def visit_UnaryOp(self, node): + self.write("(") + self.write(self.unop[node.op.__class__.__name__]) + self.write(" ") + self.traverse(node.operand) + self.write(")") + + binop = { + "Add": "+", + "Sub": "-", + "Mult": "*", + "MatMult": "@", + "Div": "/", + "Mod": "%", + "LShift": "<<", + "RShift": ">>", + "BitOr": "|", + "BitXor": "^", + "BitAnd": "&", + "FloorDiv": "//", + "Pow": "**", + } + + def visit_BinOp(self, node): + self.write("(") + self.traverse(node.left) + self.write(" " + self.binop[node.op.__class__.__name__] + " ") + self.traverse(node.right) + self.write(")") + + cmpops = { + "Eq": "==", + "NotEq": "!=", + "Lt": "<", + "LtE": "<=", + "Gt": ">", + "GtE": ">=", + "Is": "is", + "IsNot": "is not", + "In": "in", + "NotIn": "not in", + } + + def visit_Compare(self, node): + self.write("(") + self.traverse(node.left) + for o, e in zip(node.ops, node.comparators): + self.write(" " + self.cmpops[o.__class__.__name__] + " ") + self.traverse(e) + self.write(")") + + boolops = {And: "and", Or: "or"} + + def visit_BoolOp(self, node): + self.write("(") + s = " %s " % self.boolops[node.op.__class__] + self.interleave(lambda: self.write(s), self.traverse, node.values) + self.write(")") + + def visit_Attribute(self, node): + self.traverse(node.value) + # Special case: 3.__abs__() is a syntax error, so if node.value + # is an integer literal then we need to either parenthesize + # it or add an extra space to get 3 .__abs__(). + if isinstance(node.value, Constant) and isinstance(node.value.value, int): + self.write(" ") + self.write(".") + self.write(node.attr) + + def visit_Call(self, node): + self.traverse(node.func) + self.write("(") + comma = False + for e in node.args: + if comma: + self.write(", ") + else: + comma = True + self.traverse(e) + for e in node.keywords: + if comma: + self.write(", ") + else: + comma = True + self.traverse(e) + self.write(")") + + def visit_Subscript(self, node): + self.traverse(node.value) + self.write("[") + self.traverse(node.slice) + self.write("]") + + def visit_Starred(self, node): + self.write("*") + self.traverse(node.value) + + def visit_Ellipsis(self, node): + self.write("...") + + def visit_Index(self, node): + self.traverse(node.value) + + def visit_Slice(self, node): + if node.lower: + self.traverse(node.lower) + self.write(":") + if node.upper: + self.traverse(node.upper) + if node.step: + self.write(":") + self.traverse(node.step) + + def visit_ExtSlice(self, node): + self.interleave(lambda: self.write(", "), self.traverse, node.dims) + + def visit_arg(self, node): + self.write(node.arg) + if node.annotation: + self.write(": ") + self.traverse(node.annotation) + + def visit_arguments(self, node): + first = True + # normal arguments + all_args = node.posonlyargs + node.args + defaults = [None] * (len(all_args) - len(node.defaults)) + node.defaults + for index, elements in enumerate(zip(all_args, defaults), 1): + a, d = elements + if first: + first = False + else: + self.write(", ") + self.traverse(a) + if d: + self.write("=") + self.traverse(d) + if index == len(node.posonlyargs): + self.write(", /") + + # varargs, or bare '*' if no varargs but keyword-only arguments present + if node.vararg or node.kwonlyargs: + if first: + first = False + else: + self.write(", ") + self.write("*") + if node.vararg: + self.write(node.vararg.arg) + if node.vararg.annotation: + self.write(": ") + self.traverse(node.vararg.annotation) + + # keyword-only arguments + if node.kwonlyargs: + for a, d in zip(node.kwonlyargs, node.kw_defaults): + if first: + first = False + else: + self.write(", ") + self.traverse(a), + if d: + self.write("=") + self.traverse(d) + + # kwargs + if node.kwarg: + if first: + first = False + else: + self.write(", ") + self.write("**" + node.kwarg.arg) + if node.kwarg.annotation: + self.write(": ") + self.traverse(node.kwarg.annotation) + + def visit_keyword(self, node): + if node.arg is None: + self.write("**") + else: + self.write(node.arg) + self.write("=") + self.traverse(node.value) + + def visit_Lambda(self, node): + self.write("(") + self.write("lambda ") + self.traverse(node.args) + self.write(": ") + self.traverse(node.body) + self.write(")") + + def visit_alias(self, node): + self.write(node.name) + if node.asname: + self.write(" as " + node.asname) + + def visit_withitem(self, node): + self.traverse(node.context_expr) + if node.optional_vars: + self.write(" as ") + self.traverse(node.optional_vars) + +def unparse(ast_obj): + unparser = _Unparser() + return unparser.visit(ast_obj) + def main(): import argparse diff --git a/Lib/test/test_tools/test_unparse.py b/Lib/test/test_unparse.py similarity index 76% rename from Lib/test/test_tools/test_unparse.py rename to Lib/test/test_unparse.py index a958ebb51cc3d..9197c8a4a9eae 100644 --- a/Lib/test/test_tools/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -3,19 +3,12 @@ import unittest import test.support import io -import os +import pathlib import random import tokenize import ast +import functools -from test.test_tools import basepath, toolsdir, skip_if_missing - -skip_if_missing() - -parser_path = os.path.join(toolsdir, "parser") - -with test.support.DirsOnSysPath(parser_path): - import unparse def read_pyfile(filename): """Read and return the contents of a Python source file (as a @@ -26,6 +19,7 @@ def read_pyfile(filename): source = pyfile.read() return source + for_else = """\ def f(): for x in range(10): @@ -119,18 +113,21 @@ class Foo: pass suite1 """ + class ASTTestCase(unittest.TestCase): def assertASTEqual(self, ast1, ast2): self.assertEqual(ast.dump(ast1), ast.dump(ast2)) - def check_roundtrip(self, code1, filename="internal"): - ast1 = compile(code1, filename, "exec", ast.PyCF_ONLY_AST) - unparse_buffer = io.StringIO() - unparse.Unparser(ast1, unparse_buffer) - code2 = unparse_buffer.getvalue() - ast2 = compile(code2, filename, "exec", ast.PyCF_ONLY_AST) + def check_roundtrip(self, code1): + ast1 = ast.parse(code1) + code2 = ast.unparse(ast1) + ast2 = ast.parse(code2) self.assertASTEqual(ast1, ast2) + def check_invalid(self, node, raises=ValueError): + self.assertRaises(raises, ast.unparse, node) + + class UnparseTestCase(ASTTestCase): # Tests for specific bugs found in earlier versions of unparse @@ -174,8 +171,8 @@ def test_huge_float(self): self.check_roundtrip("-1e1000j") def test_min_int(self): - self.check_roundtrip(str(-2**31)) - self.check_roundtrip(str(-2**63)) + self.check_roundtrip(str(-(2 ** 31))) + self.check_roundtrip(str(-(2 ** 63))) def test_imaginary_literals(self): self.check_roundtrip("7j") @@ -265,54 +262,67 @@ def test_dict_unpacking_in_dict(self): self.check_roundtrip(r"""{**{'y': 2}, 'x': 1}""") self.check_roundtrip(r"""{**{'y': 2}, **{'x': 1}}""") + def test_invalid_raise(self): + self.check_invalid(ast.Raise(exc=None, cause=ast.Name(id="X"))) + + def test_invalid_fstring_constant(self): + self.check_invalid(ast.JoinedStr(values=[ast.Constant(value=100)])) + + def test_invalid_fstring_conversion(self): + self.check_invalid( + ast.FormattedValue( + value=ast.Constant(value="a", kind=None), + conversion=ord("Y"), # random character + format_spec=None, + ) + ) + + def test_invalid_set(self): + self.check_invalid(ast.Set(elts=[])) + class DirectoryTestCase(ASTTestCase): """Test roundtrip behaviour on all files in Lib and Lib/test.""" - NAMES = None - # test directories, relative to the root of the distribution - test_directories = 'Lib', os.path.join('Lib', 'test') + lib_dir = pathlib.Path(__file__).parent / ".." + test_directories = (lib_dir, lib_dir / "test") + skip_files = {"test_fstring.py"} - @classmethod - def get_names(cls): - if cls.NAMES is not None: - return cls.NAMES + @functools.cached_property + def files_to_test(self): + # bpo-31174: Use cached_property to store the names sample + # to always test the same files. It prevents false alarms + # when hunting reference leaks. - names = [] - for d in cls.test_directories: - test_dir = os.path.join(basepath, d) - for n in os.listdir(test_dir): - if n.endswith('.py') and not n.startswith('bad'): - names.append(os.path.join(test_dir, n)) + items = [ + item.resolve() + for directory in self.test_directories + for item in directory.glob("*.py") + if not item.name.startswith("bad") + ] # Test limited subset of files unless the 'cpu' resource is specified. if not test.support.is_resource_enabled("cpu"): - names = random.sample(names, 10) - # bpo-31174: Store the names sample to always test the same files. - # It prevents false alarms when hunting reference leaks. - cls.NAMES = names - return names + items = random.sample(items, 10) + return items def test_files(self): - # get names of files to test - names = self.get_names() - - for filename in names: + for item in self.files_to_test: if test.support.verbose: - print('Testing %s' % filename) + print(f"Testing {item.absolute()}") # Some f-strings are not correctly round-tripped by - # Tools/parser/unparse.py. See issue 28002 for details. - # We need to skip files that contain such f-strings. - if os.path.basename(filename) in ('test_fstring.py', ): + # Tools/parser/unparse.py. See issue 28002 for details. + # We need to skip files that contain such f-strings. + if item.name in self.skip_files: if test.support.verbose: - print(f'Skipping {filename}: see issue 28002') + print(f"Skipping {item.absolute()}: see issue 28002") continue - with self.subTest(filename=filename): - source = read_pyfile(filename) + with self.subTest(filename=item): + source = read_pyfile(item) self.check_roundtrip(source) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-11-20-22-43-48.bpo-38870.rLVZEv.rst b/Misc/NEWS.d/next/Library/2019-11-20-22-43-48.bpo-38870.rLVZEv.rst new file mode 100644 index 0000000000000..61af368ba556f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-20-22-43-48.bpo-38870.rLVZEv.rst @@ -0,0 +1,4 @@ +Expose :func:`ast.unparse` as a function of the :mod:`ast` module that can +be used to unparse an :class:`ast.AST` object and produce a string with code +that would produce an equivalent :class:`ast.AST` object when parsed. Patch +by Pablo Galindo and Batuhan Taskaya. diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py deleted file mode 100644 index a5cc000676b02..0000000000000 --- a/Tools/parser/unparse.py +++ /dev/null @@ -1,704 +0,0 @@ -"Usage: unparse.py " -import sys -import ast -import tokenize -import io -import os - -# Large float and imaginary literals get turned into infinities in the AST. -# We unparse those infinities to INFSTR. -INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) - -def interleave(inter, f, seq): - """Call f on each item in seq, calling inter() in between. - """ - seq = iter(seq) - try: - f(next(seq)) - except StopIteration: - pass - else: - for x in seq: - inter() - f(x) - -class Unparser: - """Methods in this class recursively traverse an AST and - output source code for the abstract syntax; original formatting - is disregarded. """ - - def __init__(self, tree, file = sys.stdout): - """Unparser(tree, file=sys.stdout) -> None. - Print the source for tree to file.""" - self.f = file - self._indent = 0 - self.dispatch(tree) - print("", file=self.f) - self.f.flush() - - def fill(self, text = ""): - "Indent a piece of text, according to the current indentation level" - self.f.write("\n"+" "*self._indent + text) - - def write(self, text): - "Append a piece of text to the current line." - self.f.write(text) - - def enter(self): - "Print ':', and increase the indentation." - self.write(":") - self._indent += 1 - - def leave(self): - "Decrease the indentation level." - self._indent -= 1 - - def dispatch(self, tree): - "Dispatcher function, dispatching tree type T to method _T." - if isinstance(tree, list): - for t in tree: - self.dispatch(t) - return - meth = getattr(self, "_"+tree.__class__.__name__) - meth(tree) - - - ############### Unparsing methods ###################### - # There should be one method per concrete grammar type # - # Constructors should be grouped by sum type. Ideally, # - # this would follow the order in the grammar, but # - # currently doesn't. # - ######################################################## - - def _Module(self, tree): - for stmt in tree.body: - self.dispatch(stmt) - - # stmt - def _Expr(self, tree): - self.fill() - self.dispatch(tree.value) - - def _NamedExpr(self, tree): - self.write("(") - self.dispatch(tree.target) - self.write(" := ") - self.dispatch(tree.value) - self.write(")") - - def _Import(self, t): - self.fill("import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - - def _ImportFrom(self, t): - self.fill("from ") - self.write("." * t.level) - if t.module: - self.write(t.module) - self.write(" import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - - def _Assign(self, t): - self.fill() - for target in t.targets: - self.dispatch(target) - self.write(" = ") - self.dispatch(t.value) - - def _AugAssign(self, t): - self.fill() - self.dispatch(t.target) - self.write(" "+self.binop[t.op.__class__.__name__]+"= ") - self.dispatch(t.value) - - def _AnnAssign(self, t): - self.fill() - if not t.simple and isinstance(t.target, ast.Name): - self.write('(') - self.dispatch(t.target) - if not t.simple and isinstance(t.target, ast.Name): - self.write(')') - self.write(": ") - self.dispatch(t.annotation) - if t.value: - self.write(" = ") - self.dispatch(t.value) - - def _Return(self, t): - self.fill("return") - if t.value: - self.write(" ") - self.dispatch(t.value) - - def _Pass(self, t): - self.fill("pass") - - def _Break(self, t): - self.fill("break") - - def _Continue(self, t): - self.fill("continue") - - def _Delete(self, t): - self.fill("del ") - interleave(lambda: self.write(", "), self.dispatch, t.targets) - - def _Assert(self, t): - self.fill("assert ") - self.dispatch(t.test) - if t.msg: - self.write(", ") - self.dispatch(t.msg) - - def _Global(self, t): - self.fill("global ") - interleave(lambda: self.write(", "), self.write, t.names) - - def _Nonlocal(self, t): - self.fill("nonlocal ") - interleave(lambda: self.write(", "), self.write, t.names) - - def _Await(self, t): - self.write("(") - self.write("await") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _Yield(self, t): - self.write("(") - self.write("yield") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _YieldFrom(self, t): - self.write("(") - self.write("yield from") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _Raise(self, t): - self.fill("raise") - if not t.exc: - assert not t.cause - return - self.write(" ") - self.dispatch(t.exc) - if t.cause: - self.write(" from ") - self.dispatch(t.cause) - - def _Try(self, t): - self.fill("try") - self.enter() - self.dispatch(t.body) - self.leave() - for ex in t.handlers: - self.dispatch(ex) - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - if t.finalbody: - self.fill("finally") - self.enter() - self.dispatch(t.finalbody) - self.leave() - - def _ExceptHandler(self, t): - self.fill("except") - if t.type: - self.write(" ") - self.dispatch(t.type) - if t.name: - self.write(" as ") - self.write(t.name) - self.enter() - self.dispatch(t.body) - self.leave() - - def _ClassDef(self, t): - self.write("\n") - for deco in t.decorator_list: - self.fill("@") - self.dispatch(deco) - self.fill("class "+t.name) - self.write("(") - comma = False - for e in t.bases: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - for e in t.keywords: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - self.write(")") - - self.enter() - self.dispatch(t.body) - self.leave() - - def _FunctionDef(self, t): - self.__FunctionDef_helper(t, "def") - - def _AsyncFunctionDef(self, t): - self.__FunctionDef_helper(t, "async def") - - def __FunctionDef_helper(self, t, fill_suffix): - self.write("\n") - for deco in t.decorator_list: - self.fill("@") - self.dispatch(deco) - def_str = fill_suffix+" "+t.name + "(" - self.fill(def_str) - self.dispatch(t.args) - self.write(")") - if t.returns: - self.write(" -> ") - self.dispatch(t.returns) - self.enter() - self.dispatch(t.body) - self.leave() - - def _For(self, t): - self.__For_helper("for ", t) - - def _AsyncFor(self, t): - self.__For_helper("async for ", t) - - def __For_helper(self, fill, t): - self.fill(fill) - self.dispatch(t.target) - self.write(" in ") - self.dispatch(t.iter) - self.enter() - self.dispatch(t.body) - self.leave() - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _If(self, t): - self.fill("if ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - # collapse nested ifs into equivalent elifs. - while (t.orelse and len(t.orelse) == 1 and - isinstance(t.orelse[0], ast.If)): - t = t.orelse[0] - self.fill("elif ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - # final else - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _While(self, t): - self.fill("while ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _With(self, t): - self.fill("with ") - interleave(lambda: self.write(", "), self.dispatch, t.items) - self.enter() - self.dispatch(t.body) - self.leave() - - def _AsyncWith(self, t): - self.fill("async with ") - interleave(lambda: self.write(", "), self.dispatch, t.items) - self.enter() - self.dispatch(t.body) - self.leave() - - # expr - def _JoinedStr(self, t): - self.write("f") - string = io.StringIO() - self._fstring_JoinedStr(t, string.write) - self.write(repr(string.getvalue())) - - def _FormattedValue(self, t): - self.write("f") - string = io.StringIO() - self._fstring_FormattedValue(t, string.write) - self.write(repr(string.getvalue())) - - def _fstring_JoinedStr(self, t, write): - for value in t.values: - meth = getattr(self, "_fstring_" + type(value).__name__) - meth(value, write) - - def _fstring_Constant(self, t, write): - assert isinstance(t.value, str) - value = t.value.replace("{", "{{").replace("}", "}}") - write(value) - - def _fstring_FormattedValue(self, t, write): - write("{") - expr = io.StringIO() - Unparser(t.value, expr) - expr = expr.getvalue().rstrip("\n") - if expr.startswith("{"): - write(" ") # Separate pair of opening brackets as "{ {" - write(expr) - if t.conversion != -1: - conversion = chr(t.conversion) - assert conversion in "sra" - write(f"!{conversion}") - if t.format_spec: - write(":") - meth = getattr(self, "_fstring_" + type(t.format_spec).__name__) - meth(t.format_spec, write) - write("}") - - def _Name(self, t): - self.write(t.id) - - def _write_constant(self, value): - if isinstance(value, (float, complex)): - # Substitute overflowing decimal literal for AST infinities. - self.write(repr(value).replace("inf", INFSTR)) - else: - self.write(repr(value)) - - def _Constant(self, t): - value = t.value - if isinstance(value, tuple): - self.write("(") - if len(value) == 1: - self._write_constant(value[0]) - self.write(",") - else: - interleave(lambda: self.write(", "), self._write_constant, value) - self.write(")") - elif value is ...: - self.write("...") - else: - if t.kind == "u": - self.write("u") - self._write_constant(t.value) - - def _List(self, t): - self.write("[") - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write("]") - - def _ListComp(self, t): - self.write("[") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write("]") - - def _GeneratorExp(self, t): - self.write("(") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write(")") - - def _SetComp(self, t): - self.write("{") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write("}") - - def _DictComp(self, t): - self.write("{") - self.dispatch(t.key) - self.write(": ") - self.dispatch(t.value) - for gen in t.generators: - self.dispatch(gen) - self.write("}") - - def _comprehension(self, t): - if t.is_async: - self.write(" async for ") - else: - self.write(" for ") - self.dispatch(t.target) - self.write(" in ") - self.dispatch(t.iter) - for if_clause in t.ifs: - self.write(" if ") - self.dispatch(if_clause) - - def _IfExp(self, t): - self.write("(") - self.dispatch(t.body) - self.write(" if ") - self.dispatch(t.test) - self.write(" else ") - self.dispatch(t.orelse) - self.write(")") - - def _Set(self, t): - assert(t.elts) # should be at least one element - self.write("{") - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write("}") - - def _Dict(self, t): - self.write("{") - def write_key_value_pair(k, v): - self.dispatch(k) - self.write(": ") - self.dispatch(v) - - def write_item(item): - k, v = item - if k is None: - # for dictionary unpacking operator in dicts {**{'y': 2}} - # see PEP 448 for details - self.write("**") - self.dispatch(v) - else: - write_key_value_pair(k, v) - interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values)) - self.write("}") - - def _Tuple(self, t): - self.write("(") - if len(t.elts) == 1: - elt = t.elts[0] - self.dispatch(elt) - self.write(",") - else: - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write(")") - - unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} - def _UnaryOp(self, t): - self.write("(") - self.write(self.unop[t.op.__class__.__name__]) - self.write(" ") - self.dispatch(t.operand) - self.write(")") - - binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%", - "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&", - "FloorDiv":"//", "Pow": "**"} - def _BinOp(self, t): - self.write("(") - self.dispatch(t.left) - self.write(" " + self.binop[t.op.__class__.__name__] + " ") - self.dispatch(t.right) - self.write(")") - - cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", - "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} - def _Compare(self, t): - self.write("(") - self.dispatch(t.left) - for o, e in zip(t.ops, t.comparators): - self.write(" " + self.cmpops[o.__class__.__name__] + " ") - self.dispatch(e) - self.write(")") - - boolops = {ast.And: 'and', ast.Or: 'or'} - def _BoolOp(self, t): - self.write("(") - s = " %s " % self.boolops[t.op.__class__] - interleave(lambda: self.write(s), self.dispatch, t.values) - self.write(")") - - def _Attribute(self,t): - self.dispatch(t.value) - # Special case: 3.__abs__() is a syntax error, so if t.value - # is an integer literal then we need to either parenthesize - # it or add an extra space to get 3 .__abs__(). - if isinstance(t.value, ast.Constant) and isinstance(t.value.value, int): - self.write(" ") - self.write(".") - self.write(t.attr) - - def _Call(self, t): - self.dispatch(t.func) - self.write("(") - comma = False - for e in t.args: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - for e in t.keywords: - if comma: self.write(", ") - else: comma = True - self.dispatch(e) - self.write(")") - - def _Subscript(self, t): - self.dispatch(t.value) - self.write("[") - self.dispatch(t.slice) - self.write("]") - - def _Starred(self, t): - self.write("*") - self.dispatch(t.value) - - # slice - def _Ellipsis(self, t): - self.write("...") - - def _Index(self, t): - self.dispatch(t.value) - - def _Slice(self, t): - if t.lower: - self.dispatch(t.lower) - self.write(":") - if t.upper: - self.dispatch(t.upper) - if t.step: - self.write(":") - self.dispatch(t.step) - - def _ExtSlice(self, t): - interleave(lambda: self.write(', '), self.dispatch, t.dims) - - # argument - def _arg(self, t): - self.write(t.arg) - if t.annotation: - self.write(": ") - self.dispatch(t.annotation) - - # others - def _arguments(self, t): - first = True - # normal arguments - all_args = t.posonlyargs + t.args - defaults = [None] * (len(all_args) - len(t.defaults)) + t.defaults - for index, elements in enumerate(zip(all_args, defaults), 1): - a, d = elements - if first:first = False - else: self.write(", ") - self.dispatch(a) - if d: - self.write("=") - self.dispatch(d) - if index == len(t.posonlyargs): - self.write(", /") - - # varargs, or bare '*' if no varargs but keyword-only arguments present - if t.vararg or t.kwonlyargs: - if first:first = False - else: self.write(", ") - self.write("*") - if t.vararg: - self.write(t.vararg.arg) - if t.vararg.annotation: - self.write(": ") - self.dispatch(t.vararg.annotation) - - # keyword-only arguments - if t.kwonlyargs: - for a, d in zip(t.kwonlyargs, t.kw_defaults): - if first:first = False - else: self.write(", ") - self.dispatch(a), - if d: - self.write("=") - self.dispatch(d) - - # kwargs - if t.kwarg: - if first:first = False - else: self.write(", ") - self.write("**"+t.kwarg.arg) - if t.kwarg.annotation: - self.write(": ") - self.dispatch(t.kwarg.annotation) - - def _keyword(self, t): - if t.arg is None: - self.write("**") - else: - self.write(t.arg) - self.write("=") - self.dispatch(t.value) - - def _Lambda(self, t): - self.write("(") - self.write("lambda ") - self.dispatch(t.args) - self.write(": ") - self.dispatch(t.body) - self.write(")") - - def _alias(self, t): - self.write(t.name) - if t.asname: - self.write(" as "+t.asname) - - def _withitem(self, t): - self.dispatch(t.context_expr) - if t.optional_vars: - self.write(" as ") - self.dispatch(t.optional_vars) - -def roundtrip(filename, output=sys.stdout): - with open(filename, "rb") as pyfile: - encoding = tokenize.detect_encoding(pyfile.readline)[0] - with open(filename, "r", encoding=encoding) as pyfile: - source = pyfile.read() - tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST) - Unparser(tree, output) - - - -def testdir(a): - try: - names = [n for n in os.listdir(a) if n.endswith('.py')] - except OSError: - print("Directory not readable: %s" % a, file=sys.stderr) - else: - for n in names: - fullname = os.path.join(a, n) - if os.path.isfile(fullname): - output = io.StringIO() - print('Testing %s' % fullname) - try: - roundtrip(fullname, output) - except Exception as e: - print(' Failed to compile, exception is %s' % repr(e)) - elif os.path.isdir(fullname): - testdir(fullname) - -def main(args): - if args[0] == '--testdir': - for a in args[1:]: - testdir(a) - else: - for a in args: - roundtrip(a) - -if __name__=='__main__': - main(sys.argv[1:]) From webhook-mailer at python.org Mon Nov 25 06:17:07 2019 From: webhook-mailer at python.org (Pablo Galindo) Date: Mon, 25 Nov 2019 11:17:07 -0000 Subject: [Python-checkins] Fix typo in Doc/whatsnew/3.9.rst (GH-17372) Message-ID: https://github.com/python/cpython/commit/e11f25dbd85709ed370e83348da07be03e9b3d7a commit: e11f25dbd85709ed370e83348da07be03e9b3d7a branch: master author: Pablo Galindo committer: GitHub date: 2019-11-25T11:16:39Z summary: Fix typo in Doc/whatsnew/3.9.rst (GH-17372) files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 9af5259de95dd..5c669a013c19d 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -121,7 +121,7 @@ Added the *indent* option to :func:`~ast.dump` which allows it to produce a multiline indented output. (Contributed by Serhiy Storchaka in :issue:`37995`.) -Added the :func:`ast.unparse` as a function in the :mod:`ast` module that can +Added :func:`ast.unparse` as a function in the :mod:`ast` module that can be used to unparse an :class:`ast.AST` object and produce a string with code that would produce an equivalent :class:`ast.AST` object when parsed. (Contributed by Pablo Galindo and Batuhan Taskaya in :issue:`38870`.) From webhook-mailer at python.org Mon Nov 25 06:49:22 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 25 Nov 2019 11:49:22 -0000 Subject: [Python-checkins] bpo-38870: Remove dependency on contextlib to avoid performance regression on import (GH-17376) Message-ID: https://github.com/python/cpython/commit/ded8888fbc33011dd39b7b1c86a5adfacc4943f3 commit: ded8888fbc33011dd39b7b1c86a5adfacc4943f3 branch: master author: Pablo Galindo committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-25T03:49:17-08:00 summary: bpo-38870: Remove dependency on contextlib to avoid performance regression on import (GH-17376) https://bugs.python.org/issue38870 Automerge-Triggered-By: @pablogsal files: M Lib/ast.py diff --git a/Lib/ast.py b/Lib/ast.py index 97914ebc66858..77eb24971ed24 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -26,7 +26,6 @@ """ import sys from _ast import * -from contextlib import contextmanager def parse(source, filename='', mode='exec', *, @@ -597,15 +596,22 @@ def buffer(self): self._buffer.clear() return value - @contextmanager - def block(self): + class _Block: """A context manager for preparing the source for blocks. It adds the character':', increases the indentation on enter and decreases the indentation on exit.""" - self.write(":") - self._indent += 1 - yield - self._indent -= 1 + def __init__(self, unparser): + self.unparser = unparser + + def __enter__(self): + self.unparser.write(":") + self.unparser._indent += 1 + + def __exit__(self, exc_type, exc_value, traceback): + self.unparser._indent -= 1 + + def block(self): + return self._Block(self) def traverse(self, node): if isinstance(node, list): From webhook-mailer at python.org Mon Nov 25 10:36:29 2019 From: webhook-mailer at python.org (Stefan Behnel) Date: Mon, 25 Nov 2019 15:36:29 -0000 Subject: [Python-checkins] bpo-20928: support base-URL and recursive includes in etree.ElementInclude (#5723) Message-ID: https://github.com/python/cpython/commit/c6a7bdb356835c9d7513b1ea6846683d446fe6c3 commit: c6a7bdb356835c9d7513b1ea6846683d446fe6c3 branch: master author: Stefan Behnel committer: GitHub date: 2019-11-25T16:36:25+01:00 summary: bpo-20928: support base-URL and recursive includes in etree.ElementInclude (#5723) * bpo-20928: bring elementtree's XInclude support en-par with the implementation in lxml by adding support for recursive includes and a base-URL. * bpo-20928: Support xincluding the same file multiple times, just not recursively. * bpo-20928: Add 'max_depth' parameter to xinclude that limits the maximum recursion depth to 6 by default. * Add news entry for updated ElementInclude support files: A Misc/NEWS.d/next/Library/2018-03-30-16-18-12.bpo-20928.ieXu6I.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementInclude.py diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 9fbb4ac1813ac..09c234ca6890a 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1668,6 +1668,17 @@ def test_unknown_event(self): """.format(html.escape(SIMPLE_XMLFILE, True)) +XINCLUDE["include_c1_repeated.xml"] = """\ + + +

    The following is the source code of Recursive1.xml:

    + + + + +
    +""" + # # badly formatted xi:include tags @@ -1688,6 +1699,31 @@ def test_unknown_event(self): """ +XINCLUDE["Recursive1.xml"] = """\ + + +

    The following is the source code of Recursive2.xml:

    + +
    +""" + +XINCLUDE["Recursive2.xml"] = """\ + + +

    The following is the source code of Recursive3.xml:

    + +
    +""" + +XINCLUDE["Recursive3.xml"] = """\ + + +

    The following is the source code of Recursive1.xml:

    + +
    +""" + + class XIncludeTest(unittest.TestCase): def xinclude_loader(self, href, parse="xml", encoding=None): @@ -1789,6 +1825,13 @@ def test_xinclude(self): ' \n' '') # C5 + def test_xinclude_repeated(self): + from xml.etree import ElementInclude + + document = self.xinclude_loader("include_c1_repeated.xml") + ElementInclude.include(document, self.xinclude_loader) + self.assertEqual(1+4*2, len(document.findall(".//p"))) + def test_xinclude_failures(self): from xml.etree import ElementInclude @@ -1821,6 +1864,45 @@ def test_xinclude_failures(self): "xi:fallback tag must be child of xi:include " "('{http://www.w3.org/2001/XInclude}fallback')") + # Test infinitely recursive includes. + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.FatalIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader) + self.assertEqual(str(cm.exception), + "recursive include of Recursive2.xml") + + # Test 'max_depth' limitation. + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.FatalIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader, max_depth=None) + self.assertEqual(str(cm.exception), + "recursive include of Recursive2.xml") + + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.LimitedRecursiveIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader, max_depth=0) + self.assertEqual(str(cm.exception), + "maximum xinclude depth reached when including file Recursive2.xml") + + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.LimitedRecursiveIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader, max_depth=1) + self.assertEqual(str(cm.exception), + "maximum xinclude depth reached when including file Recursive3.xml") + + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.LimitedRecursiveIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader, max_depth=2) + self.assertEqual(str(cm.exception), + "maximum xinclude depth reached when including file Recursive1.xml") + + document = self.xinclude_loader("Recursive1.xml") + with self.assertRaises(ElementInclude.FatalIncludeError) as cm: + ElementInclude.include(document, self.xinclude_loader, max_depth=3) + self.assertEqual(str(cm.exception), + "recursive include of Recursive2.xml") + + # -------------------------------------------------------------------- # reported bugs diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py index 963470e3b15c7..5303062716c47 100644 --- a/Lib/xml/etree/ElementInclude.py +++ b/Lib/xml/etree/ElementInclude.py @@ -50,18 +50,28 @@ import copy from . import ElementTree +from urllib.parse import urljoin XINCLUDE = "{http://www.w3.org/2001/XInclude}" XINCLUDE_INCLUDE = XINCLUDE + "include" XINCLUDE_FALLBACK = XINCLUDE + "fallback" +# For security reasons, the inclusion depth is limited to this read-only value by default. +DEFAULT_MAX_INCLUSION_DEPTH = 6 + + ## # Fatal include error. class FatalIncludeError(SyntaxError): pass + +class LimitedRecursiveIncludeError(FatalIncludeError): + pass + + ## # Default loader. This loader reads an included resource from disk. # @@ -92,13 +102,33 @@ def default_loader(href, parse, encoding=None): # @param loader Optional resource loader. If omitted, it defaults # to {@link default_loader}. If given, it should be a callable # that implements the same interface as default_loader. +# @param base_url The base URL of the original file, to resolve +# relative include file references. +# @param max_depth The maximum number of recursive inclusions. +# Limited to reduce the risk of malicious content explosion. +# Pass a negative value to disable the limitation. +# @throws LimitedRecursiveIncludeError If the {@link max_depth} was exceeded. # @throws FatalIncludeError If the function fails to include a given # resource, or if the tree contains malformed XInclude elements. -# @throws OSError If the function fails to load a given resource. +# @throws IOError If the function fails to load a given resource. +# @returns the node or its replacement if it was an XInclude node -def include(elem, loader=None): +def include(elem, loader=None, base_url=None, + max_depth=DEFAULT_MAX_INCLUSION_DEPTH): + if max_depth is None: + max_depth = -1 + elif max_depth < 0: + raise ValueError("expected non-negative depth or None for 'max_depth', got %r" % max_depth) + + if hasattr(elem, 'getroot'): + elem = elem.getroot() if loader is None: loader = default_loader + + _include(elem, loader, base_url, max_depth, set()) + + +def _include(elem, loader, base_url, max_depth, _parent_hrefs): # look for xinclude elements i = 0 while i < len(elem): @@ -106,14 +136,24 @@ def include(elem, loader=None): if e.tag == XINCLUDE_INCLUDE: # process xinclude directive href = e.get("href") + if base_url: + href = urljoin(base_url, href) parse = e.get("parse", "xml") if parse == "xml": + if href in _parent_hrefs: + raise FatalIncludeError("recursive include of %s" % href) + if max_depth == 0: + raise LimitedRecursiveIncludeError( + "maximum xinclude depth reached when including file %s" % href) + _parent_hrefs.add(href) node = loader(href, parse) if node is None: raise FatalIncludeError( "cannot load %r as %r" % (href, parse) ) - node = copy.copy(node) + node = copy.copy(node) # FIXME: this makes little sense with recursive includes + _include(node, loader, href, max_depth - 1, _parent_hrefs) + _parent_hrefs.remove(href) if e.tail: node.tail = (node.tail or "") + e.tail elem[i] = node @@ -123,11 +163,13 @@ def include(elem, loader=None): raise FatalIncludeError( "cannot load %r as %r" % (href, parse) ) + if e.tail: + text += e.tail if i: node = elem[i-1] - node.tail = (node.tail or "") + text + (e.tail or "") + node.tail = (node.tail or "") + text else: - elem.text = (elem.text or "") + text + (e.tail or "") + elem.text = (elem.text or "") + text del elem[i] continue else: @@ -139,5 +181,5 @@ def include(elem, loader=None): "xi:fallback tag must be child of xi:include (%r)" % e.tag ) else: - include(e, loader) - i = i + 1 + _include(e, loader, base_url, max_depth, _parent_hrefs) + i += 1 diff --git a/Misc/NEWS.d/next/Library/2018-03-30-16-18-12.bpo-20928.ieXu6I.rst b/Misc/NEWS.d/next/Library/2018-03-30-16-18-12.bpo-20928.ieXu6I.rst new file mode 100644 index 0000000000000..2585400907799 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-30-16-18-12.bpo-20928.ieXu6I.rst @@ -0,0 +1 @@ +ElementTree supports recursive XInclude processing. Patch by Stefan Behnel. From webhook-mailer at python.org Mon Nov 25 17:18:13 2019 From: webhook-mailer at python.org (Brett Cannon) Date: Mon, 25 Nov 2019 22:18:13 -0000 Subject: [Python-checkins] bpo-21063: Improve module synopsis for distutils (GH-17363) Message-ID: https://github.com/python/cpython/commit/f8a6316778faff3991144c3aec4fa92d7b30a72b commit: f8a6316778faff3991144c3aec4fa92d7b30a72b branch: master author: Sanchit Khurana <54467174+GeniusLearner at users.noreply.github.com> committer: Brett Cannon <54418+brettcannon at users.noreply.github.com> date: 2019-11-25T14:17:59-08:00 summary: bpo-21063: Improve module synopsis for distutils (GH-17363) files: M Doc/distutils/apiref.rst M Doc/library/2to3.rst M Doc/library/linecache.rst M Doc/library/statistics.rst M Doc/library/zipimport.rst diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index a42d2d3559f2b..80136b8a6bcdd 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1545,7 +1545,7 @@ Python's own build procedures. ================================================= .. module:: distutils.text_file - :synopsis: provides the TextFile class, a simple interface to text files + :synopsis: Provides the TextFile class, a simple interface to text files This module provides the :class:`TextFile` class, which gives an interface to @@ -1684,7 +1684,7 @@ lines, and joining lines with backslashes. =================================================== .. module:: distutils.version - :synopsis: implements classes that represent module version numbers. + :synopsis: Implements classes that represent module version numbers. .. % todo @@ -1699,7 +1699,7 @@ lines, and joining lines with backslashes. =================================================================== .. module:: distutils.cmd - :synopsis: This module provides the abstract base class Command. This class + :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class is subclassed by the modules in the distutils.command subpackage. @@ -1792,7 +1792,7 @@ Subclasses of :class:`Command` must define the following methods. ========================================================== .. module:: distutils.command - :synopsis: This subpackage contains one module for each standard Distutils command. + :synopsis: Contains one module for each standard Distutils command. .. % \subsubsection{Individual Distutils commands} @@ -2039,7 +2039,7 @@ This is described in more detail in :pep:`301`. =================================================================== .. module:: distutils.command.check - :synopsis: Check the metadata of a package + :synopsis: Check the meta-data of a package The ``check`` command performs some tests on the meta-data of a package. diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index fa4b0a9645531..c3ff3e607e797 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -456,7 +456,7 @@ and off individually. They are described here in more detail. ------------------------------- .. module:: lib2to3 - :synopsis: the 2to3 library + :synopsis: The 2to3 library .. moduleauthor:: Guido van Rossum .. moduleauthor:: Collin Winter diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 9278fc0641fca..dd9f4ee45ba82 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -2,7 +2,7 @@ ================================================ .. module:: linecache - :synopsis: This module provides random access to individual lines from text files. + :synopsis: Provides random access to individual lines from text files. .. sectionauthor:: Moshe Zadka diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index a790ed81a5607..4c7239c1895fb 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -2,7 +2,7 @@ ======================================================= .. module:: statistics - :synopsis: mathematical statistics functions + :synopsis: Mathematical statistics functions .. moduleauthor:: Steven D'Aprano .. sectionauthor:: Steven D'Aprano diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 2138697ff0641..8ac3fb16bdb90 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -2,7 +2,7 @@ ===================================================== .. module:: zipimport - :synopsis: support for importing Python modules from ZIP archives. + :synopsis: Support for importing Python modules from ZIP archives. .. moduleauthor:: Just van Rossum From webhook-mailer at python.org Mon Nov 25 17:26:47 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Mon, 25 Nov 2019 22:26:47 -0000 Subject: [Python-checkins] bpo-21063: Improve module synopsis for distutils (GH-17363) Message-ID: https://github.com/python/cpython/commit/089387ed1f47d9443b5f28bb1863294eeac2de08 commit: 089387ed1f47d9443b5f28bb1863294eeac2de08 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-25T14:26:43-08:00 summary: bpo-21063: Improve module synopsis for distutils (GH-17363) (cherry picked from commit f8a6316778faff3991144c3aec4fa92d7b30a72b) Co-authored-by: Sanchit Khurana <54467174+GeniusLearner at users.noreply.github.com> files: M Doc/distutils/apiref.rst M Doc/library/2to3.rst M Doc/library/linecache.rst M Doc/library/statistics.rst M Doc/library/zipimport.rst diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index a42d2d3559f2b..80136b8a6bcdd 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1545,7 +1545,7 @@ Python's own build procedures. ================================================= .. module:: distutils.text_file - :synopsis: provides the TextFile class, a simple interface to text files + :synopsis: Provides the TextFile class, a simple interface to text files This module provides the :class:`TextFile` class, which gives an interface to @@ -1684,7 +1684,7 @@ lines, and joining lines with backslashes. =================================================== .. module:: distutils.version - :synopsis: implements classes that represent module version numbers. + :synopsis: Implements classes that represent module version numbers. .. % todo @@ -1699,7 +1699,7 @@ lines, and joining lines with backslashes. =================================================================== .. module:: distutils.cmd - :synopsis: This module provides the abstract base class Command. This class + :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class is subclassed by the modules in the distutils.command subpackage. @@ -1792,7 +1792,7 @@ Subclasses of :class:`Command` must define the following methods. ========================================================== .. module:: distutils.command - :synopsis: This subpackage contains one module for each standard Distutils command. + :synopsis: Contains one module for each standard Distutils command. .. % \subsubsection{Individual Distutils commands} @@ -2039,7 +2039,7 @@ This is described in more detail in :pep:`301`. =================================================================== .. module:: distutils.command.check - :synopsis: Check the metadata of a package + :synopsis: Check the meta-data of a package The ``check`` command performs some tests on the meta-data of a package. diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index fa4b0a9645531..c3ff3e607e797 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -456,7 +456,7 @@ and off individually. They are described here in more detail. ------------------------------- .. module:: lib2to3 - :synopsis: the 2to3 library + :synopsis: The 2to3 library .. moduleauthor:: Guido van Rossum .. moduleauthor:: Collin Winter diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 9278fc0641fca..dd9f4ee45ba82 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -2,7 +2,7 @@ ================================================ .. module:: linecache - :synopsis: This module provides random access to individual lines from text files. + :synopsis: Provides random access to individual lines from text files. .. sectionauthor:: Moshe Zadka diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index a790ed81a5607..4c7239c1895fb 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -2,7 +2,7 @@ ======================================================= .. module:: statistics - :synopsis: mathematical statistics functions + :synopsis: Mathematical statistics functions .. moduleauthor:: Steven D'Aprano .. sectionauthor:: Steven D'Aprano diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 2138697ff0641..8ac3fb16bdb90 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -2,7 +2,7 @@ ===================================================== .. module:: zipimport - :synopsis: support for importing Python modules from ZIP archives. + :synopsis: Support for importing Python modules from ZIP archives. .. moduleauthor:: Just van Rossum From webhook-mailer at python.org Mon Nov 25 22:07:44 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 26 Nov 2019 03:07:44 -0000 Subject: [Python-checkins] closes bpo-38803: Fix leak in posixmodule. (GH-17373) Message-ID: https://github.com/python/cpython/commit/e4db1f05e9a5828f6b287f99067362fa0e5732e8 commit: e4db1f05e9a5828f6b287f99067362fa0e5732e8 branch: master author: Eddie Elizondo committer: Benjamin Peterson date: 2019-11-25T19:07:37-08:00 summary: closes bpo-38803: Fix leak in posixmodule. (GH-17373) files: M Modules/posixmodule.c diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f7386300c5691..898547113732a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7589,6 +7589,7 @@ wait_helper(pid_t pid, int status, struct rusage *ru) /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ result = PyStructSequence_New((PyTypeObject*) struct_rusage); + Py_DECREF(struct_rusage); if (!result) return NULL; From webhook-mailer at python.org Tue Nov 26 01:17:13 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Tue, 26 Nov 2019 06:17:13 -0000 Subject: [Python-checkins] bpo-38328: Speed up the creation time of constant list and set display. (GH-17114) Message-ID: https://github.com/python/cpython/commit/6dd9b64770af8905bef293c81d541eaaf8d8df52 commit: 6dd9b64770af8905bef293c81d541eaaf8d8df52 branch: master author: Brandt Bucher committer: Inada Naoki date: 2019-11-26T15:16:53+09:00 summary: bpo-38328: Speed up the creation time of constant list and set display. (GH-17114) files: A Misc/NEWS.d/next/Core and Builtins/2019-11-11-23-44-15.bpo-38328.IFrrjq.rst M Lib/test/test_sys.py M Python/compile.c diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 9961dee754c6b..947c935f34728 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1222,7 +1222,7 @@ def get_gen(): yield 1 # list samples = [[], [1,2,3], ['1', '2', '3']] for sample in samples: - check(sample, vsize('Pn') + len(sample)*self.P) + check(list(sample), vsize('Pn') + len(sample)*self.P) # sortwrapper (list) # XXX # cmpwrapper (list) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-11-23-44-15.bpo-38328.IFrrjq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-11-23-44-15.bpo-38328.IFrrjq.rst new file mode 100644 index 0000000000000..e0c5ca7bfe891 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-11-23-44-15.bpo-38328.IFrrjq.rst @@ -0,0 +1,2 @@ +Sped up the creation time of constant :class:`list` and :class:`set` displays. +Patch by Brandt Bucher. diff --git a/Python/compile.c b/Python/compile.c index f56c015fb96a3..98a4afa168c47 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -197,6 +197,7 @@ static int compiler_visit_slice(struct compiler *, slice_ty, expr_context_ty); static int inplace_binop(struct compiler *, operator_ty); +static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t); static int expr_constant(expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); @@ -3655,6 +3656,27 @@ starunpack_helper(struct compiler *c, asdl_seq *elts, { Py_ssize_t n = asdl_seq_LEN(elts); Py_ssize_t i, nsubitems = 0, nseen = 0; + if (n > 2 && are_all_items_const(elts, 0, n)) { + PyObject *folded = PyTuple_New(n); + if (folded == NULL) { + return 0; + } + PyObject *val; + for (i = 0; i < n; i++) { + val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value; + Py_INCREF(val); + PyTuple_SET_ITEM(folded, i, val); + } + if (outer_op == BUILD_SET_UNPACK) { + Py_SETREF(folded, PyFrozenSet_New(folded)); + if (folded == NULL) { + return 0; + } + } + ADDOP_LOAD_CONST_NEW(c, folded); + ADDOP_I(c, outer_op, 1); + return 1; + } for (i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { From webhook-mailer at python.org Tue Nov 26 01:31:13 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Tue, 26 Nov 2019 06:31:13 -0000 Subject: [Python-checkins] Remove use of deprecated `array.fromstring` method (GH-17332) Message-ID: https://github.com/python/cpython/commit/386d00cc341b549800776b906bfc6b20ea40c7db commit: 386d00cc341b549800776b906bfc6b20ea40c7db branch: master author: David Coles committer: Inada Naoki date: 2019-11-26T15:31:09+09:00 summary: Remove use of deprecated `array.fromstring` method (GH-17332) files: M Doc/library/socket.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 62552bcbe24c1..2d7ca33f2927d 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1411,9 +1411,9 @@ to sockets. fds = array.array("i") # Array of ints msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: - if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS): + if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS: # Append data, ignoring any truncated integers at the end. - fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) .. availability:: most Unix platforms, possibly others. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 7615f24e6cf16..5cdfd40f5b027 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -201,7 +201,7 @@ library/readline,,:bind,"python:bind ^I rl_complete" library/smtplib,,:port,method must support that as well as a regular host:port library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) +library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" library/sqlite3,,:memory, library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" From webhook-mailer at python.org Tue Nov 26 01:37:36 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 26 Nov 2019 06:37:36 -0000 Subject: [Python-checkins] Remove use of deprecated `array.fromstring` method (GH-17332) Message-ID: https://github.com/python/cpython/commit/1f864016950079a618a916140f3abe6480a8e22d commit: 1f864016950079a618a916140f3abe6480a8e22d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-25T22:37:31-08:00 summary: Remove use of deprecated `array.fromstring` method (GH-17332) (cherry picked from commit 386d00cc341b549800776b906bfc6b20ea40c7db) Co-authored-by: David Coles files: M Doc/library/socket.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index b7262774b67bb..178d7da2e5f09 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1298,9 +1298,9 @@ to sockets. fds = array.array("i") # Array of ints msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: - if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS): + if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS: # Append data, ignoring any truncated integers at the end. - fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) .. availability:: most Unix platforms, possibly others. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 0c738f0204a2d..a3c7cf6c8a2d6 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -201,7 +201,7 @@ library/readline,,:bind,"python:bind ^I rl_complete" library/smtplib,,:port,method must support that as well as a regular host:port library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) +library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" library/sqlite3,,:memory, library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" From webhook-mailer at python.org Tue Nov 26 02:55:05 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Tue, 26 Nov 2019 07:55:05 -0000 Subject: [Python-checkins] bpo-27145: small_ints[x] could be returned in long_add and long_sub (GH-15716) Message-ID: https://github.com/python/cpython/commit/036fe85bd3e6cd01093d836d71792a1966f961e8 commit: 036fe85bd3e6cd01093d836d71792a1966f961e8 branch: master author: HongWeipeng <961365124 at qq.com> committer: Inada Naoki date: 2019-11-26T16:54:49+09:00 summary: bpo-27145: small_ints[x] could be returned in long_add and long_sub (GH-15716) files: A Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst M Lib/test/test_long.py M Objects/longobject.c diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index 53101b3badb36..7ce37e8dbd6c7 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -956,6 +956,14 @@ def test_huge_rshift_of_huge(self, size): self.assertEqual(huge >> (sys.maxsize + 1), (1 << 499) + 5) self.assertEqual(huge >> (sys.maxsize + 1000), 0) + @support.cpython_only + def test_small_ints_in_huge_calculation(self): + a = 2 ** 100 + b = -a + 1 + c = a + 1 + self.assertIs(a + b, 1) + self.assertIs(c - a, 1) + def test_small_ints(self): for i in range(-5, 257): self.assertIs(i, i + 0) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst new file mode 100644 index 0000000000000..229753a3730c1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-06-16-40-12.bpo-27145.njuCXU.rst @@ -0,0 +1 @@ +int + int and int - int operators can now return small integer singletons. Patch by hongweipeng. diff --git a/Objects/longobject.c b/Objects/longobject.c index 294308e3e126d..f0567970468a8 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3206,7 +3206,7 @@ x_sub(PyLongObject *a, PyLongObject *b) if (sign < 0) { Py_SIZE(z) = -Py_SIZE(z); } - return long_normalize(z); + return maybe_small_long(long_normalize(z)); } static PyObject * @@ -3254,13 +3254,15 @@ long_sub(PyLongObject *a, PyLongObject *b) return PyLong_FromLong(MEDIUM_VALUE(a) - MEDIUM_VALUE(b)); } if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) - z = x_sub(a, b); - else + if (Py_SIZE(b) < 0) { + z = x_sub(b, a); + } + else { z = x_add(a, b); - if (z != NULL) { - assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); + if (z != NULL) { + assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); + Py_SIZE(z) = -(Py_SIZE(z)); + } } } else { From webhook-mailer at python.org Tue Nov 26 03:38:47 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 26 Nov 2019 08:38:47 -0000 Subject: [Python-checkins] Remove use of deprecated `array.fromstring` method (GH-17332) Message-ID: https://github.com/python/cpython/commit/dadff6f6610e03a9363c52ba9c49aa923984640a commit: dadff6f6610e03a9363c52ba9c49aa923984640a branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-26T00:38:41-08:00 summary: Remove use of deprecated `array.fromstring` method (GH-17332) (cherry picked from commit 386d00cc341b549800776b906bfc6b20ea40c7db) Co-authored-by: David Coles files: M Doc/library/socket.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 12b90914bae96..ae82e43e00ff0 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1394,9 +1394,9 @@ to sockets. fds = array.array("i") # Array of ints msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize)) for cmsg_level, cmsg_type, cmsg_data in ancdata: - if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS): + if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS: # Append data, ignoring any truncated integers at the end. - fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) + fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) return msg, list(fds) .. availability:: most Unix platforms, possibly others. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 586b5db6fcc06..33fbaf69c3fbd 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -199,7 +199,7 @@ library/readline,,:bind,"python:bind ^I rl_complete" library/smtplib,,:port,method must support that as well as a regular host:port library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) +library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) library/sqlite3,,:age,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" library/sqlite3,,:memory, library/sqlite3,,:who,"cur.execute(""select * from people where name_last=:who and age=:age"", {""who"": who, ""age"": age})" From webhook-mailer at python.org Tue Nov 26 11:38:49 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 26 Nov 2019 16:38:49 -0000 Subject: [Python-checkins] bpo-22377: Fixes documentation for %Z in datetime (GH-16507) Message-ID: https://github.com/python/cpython/commit/bc441ed7c1449f06df37905ee6289aa93b85d4cb commit: bc441ed7c1449f06df37905ee6289aa93b85d4cb branch: master author: Karl Dubost committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-26T08:38:41-08:00 summary: bpo-22377: Fixes documentation for %Z in datetime (GH-16507) This fixes the issue discussed in https://bugs.python.org/issue22377 and fixes it according to the comments made by Paul Ganssle @pganssle * It clarifies which values are acceptable in the table * It extends the note with a clearer information on the valid values https://bugs.python.org/issue22377 files: A Misc/NEWS.d/next/Documentation/2019-10-01-10-53-46.bpo-22377.5ni-iC.rst M Doc/library/datetime.rst diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index b1e1b25691d8f..f9a114eeb0a75 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2362,7 +2362,7 @@ requires, and these work on all platforms with a standard C implementation. | | string if the object is | +063415, | | | | naive). | -030712.345216 | | +-----------+--------------------------------+------------------------+-------+ -| ``%Z`` | Time zone name (empty string | (empty), UTC, EST, CST | | +| ``%Z`` | Time zone name (empty string | (empty), UTC, GMT | \(6) | | | if the object is naive). | | | +-----------+--------------------------------+------------------------+-------+ | ``%j`` | Day of the year as a | 001, 002, ..., 366 | \(9) | @@ -2533,9 +2533,18 @@ Notes: In addition, providing ``'Z'`` is identical to ``'+00:00'``. ``%Z`` - If :meth:`tzname` returns ``None``, ``%Z`` is replaced by an empty - string. Otherwise ``%Z`` is replaced by the returned value, which must - be a string. + In :meth:`strftime`, ``%Z`` is replaced by an empty string if + :meth:`tzname` returns ``None``; otherwise ``%Z`` is replaced by the + returned value, which must be a string. + + :meth:`strptime` only accepts certain values for ``%Z``: + + 1. any value in ``time.tzname`` for your machine's locale + 2. the hard-coded values ``UTC`` and ``GMT`` + + So someone living in Japan may have ``JST``, ``UTC``, and ``GMT`` as + valid values, but probably not ``EST``. It will raise ``ValueError`` for + invalid values. .. versionchanged:: 3.2 When the ``%z`` directive is provided to the :meth:`strptime` method, an diff --git a/Misc/NEWS.d/next/Documentation/2019-10-01-10-53-46.bpo-22377.5ni-iC.rst b/Misc/NEWS.d/next/Documentation/2019-10-01-10-53-46.bpo-22377.5ni-iC.rst new file mode 100644 index 0000000000000..d2943f75a8436 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-10-01-10-53-46.bpo-22377.5ni-iC.rst @@ -0,0 +1,2 @@ +Improves documentation of the values that :meth:`datetime.datetime.strptime` accepts for ``%Z``. +Patch by Karl Dubost. From webhook-mailer at python.org Tue Nov 26 12:08:00 2019 From: webhook-mailer at python.org (Steve Dower) Date: Tue, 26 Nov 2019 17:08:00 -0000 Subject: [Python-checkins] bpo-38892: Improve docs for audit event (GH-17361) Message-ID: https://github.com/python/cpython/commit/e563a155be60fc0757914f87c8138f10de00bb16 commit: e563a155be60fc0757914f87c8138f10de00bb16 branch: master author: Terry Jan Reedy committer: Steve Dower date: 2019-11-26T09:07:48-08:00 summary: bpo-38892: Improve docs for audit event (GH-17361) files: A Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst M Doc/c-api/sys.rst M Doc/library/audit_events.rst M Doc/library/sys.rst diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index d3bbee23f5081..eccb8a67e82a5 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -309,7 +309,7 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_Audit(const char *event, const char *format, ...) - Raises an auditing event with any active hooks. Returns zero for success + Raise an auditing event with any active hooks. Return zero for success and non-zero with an exception set on failure. If any hooks have been added, *format* and other arguments will be used @@ -327,11 +327,16 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) - Adds to the collection of active auditing hooks. Returns zero for success - and non-zero on failure. If the runtime has been initialized, also sets an + Append the callable *hook* to the list of active auditing hooks. + Return zero for success + and non-zero on failure. If the runtime has been initialized, also set an error on failure. Hooks added through this API are called for all interpreters created by the runtime. + The *userData* pointer is passed into the hook function. Since hook + functions may be called from different runtimes, this pointer should not + refer directly to Python state. + This function is safe to call before :c:func:`Py_Initialize`. When called after runtime initialization, existing audit hooks are notified and may silently abort the operation by raising an error subclassed from @@ -342,14 +347,10 @@ accessible to C code. They all work with the current interpreter thread's :c:type:`PyTupleObject`. The hook function is always called with the GIL held by the Python interpreter that raised the event. - The *userData* pointer is passed into the hook function. Since hook - functions may be called from different runtimes, this pointer should not - refer directly to Python state. - - See :pep:`578` for a detailed description of auditing. Functions in the - runtime and standard library that raise events include the details in each - function's documentation and listed in the :ref:`audit events table - `. + See :pep:`578` for a detailed description of auditing. Functions in the + runtime and standard library that raise events are listed in the + :ref:`audit events table `. + Details are in each function's documentation. .. audit-event:: sys.addaudithook "" c.PySys_AddAuditHook diff --git a/Doc/library/audit_events.rst b/Doc/library/audit_events.rst index c23b9c618323d..3c68a1515b3ef 100644 --- a/Doc/library/audit_events.rst +++ b/Doc/library/audit_events.rst @@ -7,7 +7,7 @@ Audit events table This table contains all events raised by :func:`sys.audit` or :c:func:`PySys_Audit` calls throughout the CPython runtime and the -standard library. +standard library. These calls were added in 3.8.0 or later. See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for information on handling these events. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 4b0bcde4a8b49..2f33445a6f9f5 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -25,7 +25,7 @@ always available. .. function:: addaudithook(hook) - Adds the callable *hook* to the collection of active auditing hooks for the + Append the callable *hook* to the list of active auditing hooks for the current interpreter. When an auditing event is raised through the :func:`sys.audit` function, each @@ -35,7 +35,7 @@ always available. .. audit-event:: sys.addaudithook "" sys.addaudithook - Raises a auditing event ``sys.addaudithook`` with no arguments. If any + Raise an auditing event ``sys.addaudithook`` with no arguments. If any existing hooks raise an exception derived from :class:`Exception`, the new hook will not be added and the exception suppressed. As a result, callers cannot assume that their hook has been added unless they control @@ -74,7 +74,7 @@ always available. .. index:: single: auditing - Raises an auditing event with any active hooks. The event name is a string + Raise an auditing event with any active hooks. The event name is a string identifying the event and its associated schema, which is the number and types of arguments. The schema for a given event is considered public and stable API and should not be modified between releases. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst new file mode 100644 index 0000000000000..5df67dcbfeac9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst @@ -0,0 +1 @@ +Improve documentation for audit events table and functions. From webhook-mailer at python.org Tue Nov 26 12:14:55 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Tue, 26 Nov 2019 17:14:55 -0000 Subject: [Python-checkins] bpo-38892: Improve docs for audit event (GH-17361) Message-ID: https://github.com/python/cpython/commit/86d9933cc627c4232f9702ca0766713714ebbc53 commit: 86d9933cc627c4232f9702ca0766713714ebbc53 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-26T09:14:48-08:00 summary: bpo-38892: Improve docs for audit event (GH-17361) (cherry picked from commit e563a155be60fc0757914f87c8138f10de00bb16) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst M Doc/c-api/sys.rst M Doc/library/audit_events.rst M Doc/library/sys.rst diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index d3bbee23f5081..eccb8a67e82a5 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -309,7 +309,7 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_Audit(const char *event, const char *format, ...) - Raises an auditing event with any active hooks. Returns zero for success + Raise an auditing event with any active hooks. Return zero for success and non-zero with an exception set on failure. If any hooks have been added, *format* and other arguments will be used @@ -327,11 +327,16 @@ accessible to C code. They all work with the current interpreter thread's .. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) - Adds to the collection of active auditing hooks. Returns zero for success - and non-zero on failure. If the runtime has been initialized, also sets an + Append the callable *hook* to the list of active auditing hooks. + Return zero for success + and non-zero on failure. If the runtime has been initialized, also set an error on failure. Hooks added through this API are called for all interpreters created by the runtime. + The *userData* pointer is passed into the hook function. Since hook + functions may be called from different runtimes, this pointer should not + refer directly to Python state. + This function is safe to call before :c:func:`Py_Initialize`. When called after runtime initialization, existing audit hooks are notified and may silently abort the operation by raising an error subclassed from @@ -342,14 +347,10 @@ accessible to C code. They all work with the current interpreter thread's :c:type:`PyTupleObject`. The hook function is always called with the GIL held by the Python interpreter that raised the event. - The *userData* pointer is passed into the hook function. Since hook - functions may be called from different runtimes, this pointer should not - refer directly to Python state. - - See :pep:`578` for a detailed description of auditing. Functions in the - runtime and standard library that raise events include the details in each - function's documentation and listed in the :ref:`audit events table - `. + See :pep:`578` for a detailed description of auditing. Functions in the + runtime and standard library that raise events are listed in the + :ref:`audit events table `. + Details are in each function's documentation. .. audit-event:: sys.addaudithook "" c.PySys_AddAuditHook diff --git a/Doc/library/audit_events.rst b/Doc/library/audit_events.rst index c23b9c618323d..3c68a1515b3ef 100644 --- a/Doc/library/audit_events.rst +++ b/Doc/library/audit_events.rst @@ -7,7 +7,7 @@ Audit events table This table contains all events raised by :func:`sys.audit` or :c:func:`PySys_Audit` calls throughout the CPython runtime and the -standard library. +standard library. These calls were added in 3.8.0 or later. See :func:`sys.addaudithook` and :c:func:`PySys_AddAuditHook` for information on handling these events. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 0e15467cb1a34..8d0de479e9cf5 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -25,7 +25,7 @@ always available. .. function:: addaudithook(hook) - Adds the callable *hook* to the collection of active auditing hooks for the + Append the callable *hook* to the list of active auditing hooks for the current interpreter. When an auditing event is raised through the :func:`sys.audit` function, each @@ -35,7 +35,7 @@ always available. .. audit-event:: sys.addaudithook "" sys.addaudithook - Raises a auditing event ``sys.addaudithook`` with no arguments. If any + Raise an auditing event ``sys.addaudithook`` with no arguments. If any existing hooks raise an exception derived from :class:`Exception`, the new hook will not be added and the exception suppressed. As a result, callers cannot assume that their hook has been added unless they control @@ -74,7 +74,7 @@ always available. .. index:: single: auditing - Raises an auditing event with any active hooks. The event name is a string + Raise an auditing event with any active hooks. The event name is a string identifying the event and its associated schema, which is the number and types of arguments. The schema for a given event is considered public and stable API and should not be modified between releases. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst new file mode 100644 index 0000000000000..5df67dcbfeac9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-22-22-18-50.bpo-38892.LS586s.rst @@ -0,0 +1 @@ +Improve documentation for audit events table and functions. From webhook-mailer at python.org Tue Nov 26 15:02:31 2019 From: webhook-mailer at python.org (Brett Cannon) Date: Tue, 26 Nov 2019 20:02:31 -0000 Subject: [Python-checkins] bpo-21063: Improve module synopsis for distutils (GH-17363) (#17381) Message-ID: https://github.com/python/cpython/commit/2f2489310d89f589a091aa09ac1eb973d9a383d8 commit: 2f2489310d89f589a091aa09ac1eb973d9a383d8 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Brett Cannon <54418+brettcannon at users.noreply.github.com> date: 2019-11-26T12:02:24-08:00 summary: bpo-21063: Improve module synopsis for distutils (GH-17363) (#17381) (cherry picked from commit f8a6316778faff3991144c3aec4fa92d7b30a72b) Co-authored-by: Sanchit Khurana <54467174+GeniusLearner at users.noreply.github.com> files: M Doc/distutils/apiref.rst M Doc/library/2to3.rst M Doc/library/linecache.rst M Doc/library/statistics.rst M Doc/library/zipimport.rst diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 8efeffb6376e1..5ae84e04165f5 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1530,7 +1530,7 @@ Python's own build procedures. ================================================= .. module:: distutils.text_file - :synopsis: provides the TextFile class, a simple interface to text files + :synopsis: Provides the TextFile class, a simple interface to text files This module provides the :class:`TextFile` class, which gives an interface to @@ -1669,7 +1669,7 @@ lines, and joining lines with backslashes. =================================================== .. module:: distutils.version - :synopsis: implements classes that represent module version numbers. + :synopsis: Implements classes that represent module version numbers. .. % todo @@ -1684,7 +1684,7 @@ lines, and joining lines with backslashes. =================================================================== .. module:: distutils.cmd - :synopsis: This module provides the abstract base class Command. This class + :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class is subclassed by the modules in the distutils.command subpackage. @@ -1777,7 +1777,7 @@ Subclasses of :class:`Command` must define the following methods. ========================================================== .. module:: distutils.command - :synopsis: This subpackage contains one module for each standard Distutils command. + :synopsis: Contains one module for each standard Distutils command. .. % \subsubsection{Individual Distutils commands} @@ -2021,7 +2021,7 @@ This is described in more detail in :pep:`301`. =================================================================== .. module:: distutils.command.check - :synopsis: Check the metadata of a package + :synopsis: Check the meta-data of a package The ``check`` command performs some tests on the meta-data of a package. diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index fa4b0a9645531..c3ff3e607e797 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -456,7 +456,7 @@ and off individually. They are described here in more detail. ------------------------------- .. module:: lib2to3 - :synopsis: the 2to3 library + :synopsis: The 2to3 library .. moduleauthor:: Guido van Rossum .. moduleauthor:: Collin Winter diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 34fcac57c072d..8387de436a7bb 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -2,7 +2,7 @@ ================================================ .. module:: linecache - :synopsis: This module provides random access to individual lines from text files. + :synopsis: Provides random access to individual lines from text files. .. sectionauthor:: Moshe Zadka diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 26bb592b23812..081fafd45dda4 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -2,7 +2,7 @@ ======================================================= .. module:: statistics - :synopsis: mathematical statistics functions + :synopsis: Mathematical statistics functions .. moduleauthor:: Steven D'Aprano .. sectionauthor:: Steven D'Aprano diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index eaae2bb04b748..fddbb50bce9ab 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -2,7 +2,7 @@ ===================================================== .. module:: zipimport - :synopsis: support for importing Python modules from ZIP archives. + :synopsis: Support for importing Python modules from ZIP archives. .. moduleauthor:: Just van Rossum From webhook-mailer at python.org Tue Nov 26 17:36:07 2019 From: webhook-mailer at python.org (Ethan Furman) Date: Tue, 26 Nov 2019 22:36:07 -0000 Subject: [Python-checkins] bpo-38045: Improve the performance of _decompose() in enum.py (GH-16483) Message-ID: https://github.com/python/cpython/commit/0b41a922f95f62b620d5a197b9f2ed8e4bb70730 commit: 0b41a922f95f62b620d5a197b9f2ed8e4bb70730 branch: master author: HongWeipeng <961365124 at qq.com> committer: Ethan Furman date: 2019-11-26T14:36:02-08:00 summary: bpo-38045: Improve the performance of _decompose() in enum.py (GH-16483) * Improve the performance of _decompose() in enum.py Co-Authored-By: Brandt Bucher files: A Misc/NEWS.d/next/Library/2019-09-30-12-09-41.bpo-38045.VDRtd3.rst M Lib/enum.py diff --git a/Lib/enum.py b/Lib/enum.py index 06f42a978035b..0be1b60cd6d8a 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -861,28 +861,20 @@ def _decompose(flag, value): # _decompose is only called if the value is not named not_covered = value negative = value < 0 - # issue29167: wrap accesses to _value2member_map_ in a list to avoid race - # conditions between iterating over it and having more pseudo- - # members added to it - if negative: - # only check for named flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None - ] - else: - # check for named flags and powers-of-two flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None or _power_of_two(v) - ] members = [] - for member, member_value in flags_to_check: + for member in flag: + member_value = member.value if member_value and member_value & value == member_value: members.append(member) not_covered &= ~member_value + if not negative: + tmp = not_covered + while tmp: + flag_value = 2 ** _high_bit(tmp) + if flag_value in flag._value2member_map_: + members.append(flag._value2member_map_[flag_value]) + not_covered &= ~flag_value + tmp &= ~flag_value if not members and value in flag._value2member_map_: members.append(flag._value2member_map_[value]) members.sort(key=lambda m: m._value_, reverse=True) @@ -890,8 +882,3 @@ def _decompose(flag, value): # we have the breakdown, don't need the value member itself members.pop(0) return members, not_covered - -def _power_of_two(value): - if value < 1: - return False - return value == 2 ** _high_bit(value) diff --git a/Misc/NEWS.d/next/Library/2019-09-30-12-09-41.bpo-38045.VDRtd3.rst b/Misc/NEWS.d/next/Library/2019-09-30-12-09-41.bpo-38045.VDRtd3.rst new file mode 100644 index 0000000000000..e7e515f5c2511 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-30-12-09-41.bpo-38045.VDRtd3.rst @@ -0,0 +1 @@ +Improve the performance of :func:`enum._decompose` in :mod:`enum`. Patch by hongweipeng. From webhook-mailer at python.org Tue Nov 26 19:27:54 2019 From: webhook-mailer at python.org (Steve Dower) Date: Wed, 27 Nov 2019 00:27:54 -0000 Subject: [Python-checkins] bpo-38922: Raise code.__new__ audit event when code object replace() is called (GH-17394) Message-ID: https://github.com/python/cpython/commit/c7c01ab1e5415b772c68e15f1aba51e520010830 commit: c7c01ab1e5415b772c68e15f1aba51e520010830 branch: master author: Steve Dower committer: GitHub date: 2019-11-26T16:27:50-08:00 summary: bpo-38922: Raise code.__new__ audit event when code object replace() is called (GH-17394) files: A Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst M Objects/codeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst new file mode 100644 index 0000000000000..a7af652e5a5bd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst @@ -0,0 +1,2 @@ +Calling ``replace`` on a code object now raises the ``code.__new__`` audit +event. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 39bf6fc6f228e..f0b62ec94148d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -641,6 +641,13 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG + if (PySys_Audit("code.__new__", "OOOiiiiii", + co_code, co_filename, co_name, co_argcount, + co_posonlyargcount, co_kwonlyargcount, co_nlocals, + co_stacksize, co_flags) < 0) { + return NULL; + } + return (PyObject *)PyCode_NewWithPosOnlyArgs( co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, From webhook-mailer at python.org Tue Nov 26 19:46:36 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 27 Nov 2019 00:46:36 -0000 Subject: [Python-checkins] bpo-38922: Raise code.__new__ audit event when code object replace() is called (GH-17394) Message-ID: https://github.com/python/cpython/commit/191f94cca6f8cf59535e7459c1113e4a1cdfe201 commit: 191f94cca6f8cf59535e7459c1113e4a1cdfe201 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-26T16:46:32-08:00 summary: bpo-38922: Raise code.__new__ audit event when code object replace() is called (GH-17394) (cherry picked from commit c7c01ab1e5415b772c68e15f1aba51e520010830) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst M Objects/codeobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst new file mode 100644 index 0000000000000..a7af652e5a5bd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-12-20-34.bpo-38922.i6ja-i.rst @@ -0,0 +1,2 @@ +Calling ``replace`` on a code object now raises the ``code.__new__`` audit +event. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 39bf6fc6f228e..f0b62ec94148d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -641,6 +641,13 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG + if (PySys_Audit("code.__new__", "OOOiiiiii", + co_code, co_filename, co_name, co_argcount, + co_posonlyargcount, co_kwonlyargcount, co_nlocals, + co_stacksize, co_flags) < 0) { + return NULL; + } + return (PyObject *)PyCode_NewWithPosOnlyArgs( co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, From webhook-mailer at python.org Tue Nov 26 20:10:54 2019 From: webhook-mailer at python.org (Giampaolo Rodola) Date: Wed, 27 Nov 2019 01:10:54 -0000 Subject: [Python-checkins] bpo-38688, shutil.copytree: consume iterator and create list of entries to prevent infinite recursion (GH-17098) Message-ID: https://github.com/python/cpython/commit/9bbcbc9f6dfe1368fe7330b117707f828e6a2c18 commit: 9bbcbc9f6dfe1368fe7330b117707f828e6a2c18 branch: master author: Bruno P. Kinoshita committer: Giampaolo Rodola date: 2019-11-27T09:10:37+08:00 summary: bpo-38688, shutil.copytree: consume iterator and create list of entries to prevent infinite recursion (GH-17098) files: A Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst M Lib/shutil.py M Lib/test/test_shutil.py diff --git a/Lib/shutil.py b/Lib/shutil.py index f97de788d9d40..8f609b312d331 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -442,7 +442,7 @@ def _ignore_patterns(path, names): def _copytree(entries, src, dst, symlinks, ignore, copy_function, ignore_dangling_symlinks, dirs_exist_ok=False): if ignore is not None: - ignored_names = ignore(src, set(os.listdir(src))) + ignored_names = ignore(src, {x.name for x in entries}) else: ignored_names = set() @@ -543,11 +543,12 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, """ sys.audit("shutil.copytree", src, dst) - with os.scandir(src) as entries: - return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks, - ignore=ignore, copy_function=copy_function, - ignore_dangling_symlinks=ignore_dangling_symlinks, - dirs_exist_ok=dirs_exist_ok) + with os.scandir(src) as itr: + entries = list(itr) + return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks, + ignore=ignore, copy_function=copy_function, + ignore_dangling_symlinks=ignore_dangling_symlinks, + dirs_exist_ok=dirs_exist_ok) if hasattr(os.stat_result, 'st_file_attributes'): # Special handling for directory junctions to make them behave like diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index dd5589b2e3a5c..460b979ba9332 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -727,6 +727,17 @@ def test_copytree_return_value(self): rv = shutil.copytree(src_dir, dst_dir) self.assertEqual(['foo'], os.listdir(rv)) + def test_copytree_subdirectory(self): + # copytree where dst is a subdirectory of src, see Issue 38688 + base_dir = self.mkdtemp() + self.addCleanup(shutil.rmtree, base_dir, ignore_errors=True) + src_dir = os.path.join(base_dir, "t", "pg") + dst_dir = os.path.join(src_dir, "somevendor", "1.0") + os.makedirs(src_dir) + src = os.path.join(src_dir, 'pol') + write_file(src, 'pol') + rv = shutil.copytree(src_dir, dst_dir) + self.assertEqual(['pol'], os.listdir(rv)) class TestCopy(BaseTest, unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst b/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst new file mode 100644 index 0000000000000..28b82ab1619e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst @@ -0,0 +1,5 @@ +Calling func:`shutil.copytree` to copy a directory tree from one directory +to another subdirectory resulted in an endless loop and a RecursionError. A +fix was added to consume an iterator and create the list of the entries to +be copied, avoiding the recursion for newly created directories. Patch by +Bruno P. Kinoshita. From webhook-mailer at python.org Tue Nov 26 20:13:00 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Wed, 27 Nov 2019 01:13:00 -0000 Subject: [Python-checkins] [3.7] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) (#17379) Message-ID: https://github.com/python/cpython/commit/2fb971940b18bcf5a58b1b242b697d0f1d8ad7ef commit: 2fb971940b18bcf5a58b1b242b697d0f1d8ad7ef branch: 3.7 author: Terry Jan Reedy committer: GitHub date: 2019-11-26T20:12:56-05:00 summary: [3.7] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) (#17379) Extra newlines are removed at the end of non-shell files. If the file only has newlines after stripping other trailing whitespace, all are removed, as is done by patchcheck.py. (cherry picked from commit 6bf644ec82f14cceae68278dc35bafb00875efae) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/format.py M Lib/idlelib/help.html M Lib/idlelib/idle_test/mock_idle.py M Lib/idlelib/idle_test/test_format.py diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c22b182..273b5830e4293 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,8 @@ Format Paragraph Strip trailing whitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, - including lines within multiline strings. + including lines within multiline strings. Except for Shell windows, + remove extra newlines at the end of the file. .. index:: single: Run script diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 53348ee0af0e9..efac152e4d03c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2019-12-16? ====================================== +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 2b0980565734a..4b57a182c9a49 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,6 +408,16 @@ def do_rstrip(self, event=None): if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + if (text.get('end-2c') == '\n' # File ends with at least 1 newline; + and not hasattr(self.editwin, 'interp')): # & is not Shell. + # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop if file empty. + and text.get('end-3c') == '\n'): + text.delete('end-3c') + # Because tk indexes are slice indexes and never raise, + # a file with only newlines will be emptied. + # patchcheck.py does the same. + undo.undo_block_stop() diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f2453baf6..09dc4c57bcdc0 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a0 documentation + IDLE — Python 3.9.0a1 documentation @@ -17,14 +17,14 @@ - + @@ -62,7 +62,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,8 @@

    Edit menu (Shell and Editor)Table of Contents

    Previous topic

    -

    tkinter.scrolledtext ? Scrolled Text Widget

    +

    tkinter.tix ? Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +920,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +960,11 @@

    Navigation



    - Last updated on Sep 01, 2019. + Last updated on Nov 24, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52fd511f..71fa480ce4d05 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ def __call__(self, *args, **kwds): class Editor: '''Minimally imitate editor.EditorWindow class. ''' - def __init__(self, flist=None, filename=None, key=None, root=None): - self.text = Text() + def __init__(self, flist=None, filename=None, key=None, root=None, + text=None): # Allow real Text with mock Editor. + self.text = text or Text() self.undo = UndoDelegator() def get_selection_indices(self): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 20b5970f4982d..a79bb515089e7 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -611,37 +611,33 @@ def test_change_indentwidth(self, askinteger): class RstripTest(unittest.TestCase): - def test_rstrip_line(self): - editor = MockEditor() - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip - eq = self.assertEqual + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.editor = MockEditor(text=cls.text) + cls.do_rstrip = ft.Rstrip(cls.editor).do_rstrip + + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' ') - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' \n') - do_rstrip() - eq(text.get('1.0', 'insert'), '\n') - - def test_rstrip_multiple(self): - editor = MockEditor() - # Comment above, uncomment 3 below to test with real Editor & Text. - #from idlelib.editor import EditorWindow as Editor - #from tkinter import Tk - #editor = Editor(root=Tk()) - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip + def tearDown(self): + self.text.delete('1.0', 'end-1c') + def test_rstrip_lines(self): original = ( "Line with an ending tab \n" "Line ending in 5 spaces \n" "Linewithnospaces\n" " indented line\n" " indented line with trailing space \n" - " ") + " \n") stripped = ( "Line with an ending tab\n" "Line ending in 5 spaces\n" @@ -649,9 +645,23 @@ def test_rstrip_multiple(self): " indented line\n" " indented line with trailing space\n") - text.insert('1.0', original) - do_rstrip() - self.assertEqual(text.get('1.0', 'insert'), stripped) + self.text.insert('1.0', original) + self.do_rstrip() + self.assertEqual(self.text.get('1.0', 'insert'), stripped) + + def test_rstrip_end(self): + text = self.text + for code in ('', '\n', '\n\n\n'): + with self.subTest(code=code): + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for code in ('a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(code=code): + text.delete('1.0', 'end-1c') + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst new file mode 100644 index 0000000000000..14bab9e854bdc --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst @@ -0,0 +1,2 @@ +'Strip Trailing Whitespace' on the Format menu removes extra newlines +at the end of non-shell files. From webhook-mailer at python.org Tue Nov 26 20:13:27 2019 From: webhook-mailer at python.org (Terry Jan Reedy) Date: Wed, 27 Nov 2019 01:13:27 -0000 Subject: [Python-checkins] [3.8] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) Message-ID: https://github.com/python/cpython/commit/a9c86f5e1afa2487524b1947153953b583714d62 commit: a9c86f5e1afa2487524b1947153953b583714d62 branch: 3.8 author: Terry Jan Reedy committer: GitHub date: 2019-11-26T20:13:23-05:00 summary: [3.8] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) Extra newlines are removed at the end of non-shell files. If the file only has newlines after stripping other trailing whitespace, all are removed, as is done by patchcheck.py. (cherry picked from commit 6bf644ec82f14cceae68278dc35bafb00875efae) Co-authored-by: Terry Jan Reedy files: A Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst M Doc/library/idle.rst M Lib/idlelib/NEWS.txt M Lib/idlelib/format.py M Lib/idlelib/help.html M Lib/idlelib/idle_test/mock_idle.py M Lib/idlelib/idle_test/test_format.py diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c22b182..273b5830e4293 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,8 @@ Format Paragraph Strip trailing whitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, - including lines within multiline strings. + including lines within multiline strings. Except for Shell windows, + remove extra newlines at the end of the file. .. index:: single: Run script diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 153c7630cf8be..ed5cd4dc03b31 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2019-12-16? ====================================== +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 2b0980565734a..4b57a182c9a49 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,6 +408,16 @@ def do_rstrip(self, event=None): if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + if (text.get('end-2c') == '\n' # File ends with at least 1 newline; + and not hasattr(self.editwin, 'interp')): # & is not Shell. + # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop if file empty. + and text.get('end-3c') == '\n'): + text.delete('end-3c') + # Because tk indexes are slice indexes and never raise, + # a file with only newlines will be emptied. + # patchcheck.py does the same. + undo.undo_block_stop() diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f2453baf6..09dc4c57bcdc0 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a0 documentation + IDLE — Python 3.9.0a1 documentation @@ -17,14 +17,14 @@ - + @@ -62,7 +62,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,8 @@

    Edit menu (Shell and Editor)Table of Contents

    Previous topic

    -

    tkinter.scrolledtext ? Scrolled Text Widget

    +

    tkinter.tix ? Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +920,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +960,11 @@

    Navigation



    - Last updated on Sep 01, 2019. + Last updated on Nov 24, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52fd511f..71fa480ce4d05 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ def __call__(self, *args, **kwds): class Editor: '''Minimally imitate editor.EditorWindow class. ''' - def __init__(self, flist=None, filename=None, key=None, root=None): - self.text = Text() + def __init__(self, flist=None, filename=None, key=None, root=None, + text=None): # Allow real Text with mock Editor. + self.text = text or Text() self.undo = UndoDelegator() def get_selection_indices(self): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 20b5970f4982d..a79bb515089e7 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -611,37 +611,33 @@ def test_change_indentwidth(self, askinteger): class RstripTest(unittest.TestCase): - def test_rstrip_line(self): - editor = MockEditor() - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip - eq = self.assertEqual + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.editor = MockEditor(text=cls.text) + cls.do_rstrip = ft.Rstrip(cls.editor).do_rstrip + + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' ') - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' \n') - do_rstrip() - eq(text.get('1.0', 'insert'), '\n') - - def test_rstrip_multiple(self): - editor = MockEditor() - # Comment above, uncomment 3 below to test with real Editor & Text. - #from idlelib.editor import EditorWindow as Editor - #from tkinter import Tk - #editor = Editor(root=Tk()) - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip + def tearDown(self): + self.text.delete('1.0', 'end-1c') + def test_rstrip_lines(self): original = ( "Line with an ending tab \n" "Line ending in 5 spaces \n" "Linewithnospaces\n" " indented line\n" " indented line with trailing space \n" - " ") + " \n") stripped = ( "Line with an ending tab\n" "Line ending in 5 spaces\n" @@ -649,9 +645,23 @@ def test_rstrip_multiple(self): " indented line\n" " indented line with trailing space\n") - text.insert('1.0', original) - do_rstrip() - self.assertEqual(text.get('1.0', 'insert'), stripped) + self.text.insert('1.0', original) + self.do_rstrip() + self.assertEqual(self.text.get('1.0', 'insert'), stripped) + + def test_rstrip_end(self): + text = self.text + for code in ('', '\n', '\n\n\n'): + with self.subTest(code=code): + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for code in ('a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(code=code): + text.delete('1.0', 'end-1c') + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst new file mode 100644 index 0000000000000..14bab9e854bdc --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst @@ -0,0 +1,2 @@ +'Strip Trailing Whitespace' on the Format menu removes extra newlines +at the end of non-shell files. From webhook-mailer at python.org Tue Nov 26 23:49:44 2019 From: webhook-mailer at python.org (Giampaolo Rodola) Date: Wed, 27 Nov 2019 04:49:44 -0000 Subject: [Python-checkins] [3.8] bpo-38688, shutil.copytree: consume iterator and create list of entries to prevent infinite recursion (GH-17397) Message-ID: https://github.com/python/cpython/commit/65c92c5870944b972a879031abd4c20c4f0d7981 commit: 65c92c5870944b972a879031abd4c20c4f0d7981 branch: 3.8 author: Bruno P. Kinoshita committer: Giampaolo Rodola date: 2019-11-27T12:49:37+08:00 summary: [3.8] bpo-38688, shutil.copytree: consume iterator and create list of entries to prevent infinite recursion (GH-17397) (cherry picked from commit 9bbcbc9f6dfe1368fe7330b117707f828e6a2c18) Co-authored-by: Bruno P. Kinoshita files: A Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst M Lib/shutil.py M Lib/test/test_shutil.py diff --git a/Lib/shutil.py b/Lib/shutil.py index 1e89256cc3444..755ce392e6d9a 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -442,7 +442,7 @@ def _ignore_patterns(path, names): def _copytree(entries, src, dst, symlinks, ignore, copy_function, ignore_dangling_symlinks, dirs_exist_ok=False): if ignore is not None: - ignored_names = ignore(src, set(os.listdir(src))) + ignored_names = ignore(src, {x.name for x in entries}) else: ignored_names = set() @@ -543,11 +543,12 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, """ sys.audit("shutil.copytree", src, dst) - with os.scandir(src) as entries: - return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks, - ignore=ignore, copy_function=copy_function, - ignore_dangling_symlinks=ignore_dangling_symlinks, - dirs_exist_ok=dirs_exist_ok) + with os.scandir(src) as itr: + entries = list(itr) + return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks, + ignore=ignore, copy_function=copy_function, + ignore_dangling_symlinks=ignore_dangling_symlinks, + dirs_exist_ok=dirs_exist_ok) if hasattr(os.stat_result, 'st_file_attributes'): # Special handling for directory junctions to make them behave like diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index b98e7dc798abe..286e333a8aa9c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1605,6 +1605,18 @@ def test_copytree_return_value(self): rv = shutil.copytree(src_dir, dst_dir) self.assertEqual(['foo'], os.listdir(rv)) + def test_copytree_subdirectory(self): + # copytree where dst is a subdirectory of src, see Issue 38688 + base_dir = self.mkdtemp() + self.addCleanup(shutil.rmtree, base_dir, ignore_errors=True) + src_dir = os.path.join(base_dir, "t", "pg") + dst_dir = os.path.join(src_dir, "somevendor", "1.0") + os.makedirs(src_dir) + src = os.path.join(src_dir, 'pol') + write_file(src, 'pol') + rv = shutil.copytree(src_dir, dst_dir) + self.assertEqual(['pol'], os.listdir(rv)) + class TestWhich(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst b/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst new file mode 100644 index 0000000000000..28b82ab1619e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-22-10-45-03.bpo-38668.iKx23z.rst @@ -0,0 +1,5 @@ +Calling func:`shutil.copytree` to copy a directory tree from one directory +to another subdirectory resulted in an endless loop and a RecursionError. A +fix was added to consume an iterator and create the list of the entries to +be copied, avoiding the recursion for newly created directories. Patch by +Bruno P. Kinoshita. From webhook-mailer at python.org Tue Nov 26 23:54:50 2019 From: webhook-mailer at python.org (Zachary Ware) Date: Wed, 27 Nov 2019 04:54:50 -0000 Subject: [Python-checkins] Be more specific about the `.so` gitignore patterns (GH-17328) Message-ID: https://github.com/python/cpython/commit/1ef4c32c8d4f374adfea599f033fa61254bf951d commit: 1ef4c32c8d4f374adfea599f033fa61254bf951d branch: master author: Anthony Sottile committer: Zachary Ware date: 2019-11-26T22:54:46-06:00 summary: Be more specific about the `.so` gitignore patterns (GH-17328) In GH-15823 the pattern was changed from `libpython*.so*` to `*.so*` which matches a bit too greedily for some packagers. For instance this trips up `debian/README.source`. A more specific pattern fixes this issue. files: M .gitignore diff --git a/.gitignore b/.gitignore index b11f72f69fae5..8c1f8a43075a4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,8 @@ *.iml *.o *.a -*.so* +*.so +*.so.* *.dylib *.dll *.orig From webhook-mailer at python.org Wed Nov 27 00:08:54 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Wed, 27 Nov 2019 05:08:54 -0000 Subject: [Python-checkins] Show the differing module names for readlink() (GH-17395) Message-ID: https://github.com/python/cpython/commit/ce4b7a273a9c560ed4b1a6284ef1bbb02d8e9782 commit: ce4b7a273a9c560ed4b1a6284ef1bbb02d8e9782 branch: master author: Yoni Lavi committer: Benjamin Peterson date: 2019-11-26T21:08:50-08:00 summary: Show the differing module names for readlink() (GH-17395) This was very confusing with the text for both being just `readlink()`. files: M Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 5c669a013c19d..1cd96ef3b07af 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -184,8 +184,8 @@ case), and one used ``__VENV_NAME__`` instead. pathlib ------- -Added :meth:`~pathlib.Path.readlink()` which acts similar to -:func:`~os.readlink`. +Added :meth:`pathlib.Path.readlink()` which acts similarly to +:func:`os.readlink`. (Contributed by Girts Folkmanis in :issue:`30618`) pprint From webhook-mailer at python.org Wed Nov 27 03:46:49 2019 From: webhook-mailer at python.org (Tal Einat) Date: Wed, 27 Nov 2019 08:46:49 -0000 Subject: [Python-checkins] bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) Message-ID: https://github.com/python/cpython/commit/1bddf890e595a865414645c6041733043c4081f8 commit: 1bddf890e595a865414645c6041733043c4081f8 branch: master author: Florian Dahlitz committer: Tal Einat date: 2019-11-27T10:46:40+02:00 summary: bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 76b7035ced979..68098508afbaa 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1655,8 +1655,19 @@ class' :attr:`~object.__dict__`. Called at the time the owning class *owner* is created. The descriptor has been assigned to *name*. - .. versionadded:: 3.6 + .. note:: + + ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so + it will need to be called explicitly with the appropriate parameters when a + descriptor is added to a class after initial creation:: + descr = custom_descriptor() + cls.attr = descr + descr.__set_name__(cls, 'attr') + + See :ref:`class-object-creation` for more details. + + .. versionadded:: 3.6 The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module as specifying the class where this object was defined (setting this From webhook-mailer at python.org Wed Nov 27 03:52:43 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 27 Nov 2019 08:52:43 -0000 Subject: [Python-checkins] bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) Message-ID: https://github.com/python/cpython/commit/cd27d22ac90a869dc740004597246f24246348a6 commit: cd27d22ac90a869dc740004597246f24246348a6 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-27T00:52:39-08:00 summary: bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) (cherry picked from commit 1bddf890e595a865414645c6041733043c4081f8) Co-authored-by: Florian Dahlitz files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 835db9224cc74..7a99e1e5220bb 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1641,8 +1641,19 @@ class' :attr:`~object.__dict__`. Called at the time the owning class *owner* is created. The descriptor has been assigned to *name*. - .. versionadded:: 3.6 + .. note:: + + ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so + it will need to be called explicitly with the appropriate parameters when a + descriptor is added to a class after initial creation:: + descr = custom_descriptor() + cls.attr = descr + descr.__set_name__(cls, 'attr') + + See :ref:`class-object-creation` for more details. + + .. versionadded:: 3.6 The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module as specifying the class where this object was defined (setting this From webhook-mailer at python.org Wed Nov 27 03:53:56 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Wed, 27 Nov 2019 08:53:56 -0000 Subject: [Python-checkins] bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) Message-ID: https://github.com/python/cpython/commit/0f9c9d53283420a570850aa92869d032b40d4fba commit: 0f9c9d53283420a570850aa92869d032b40d4fba branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-27T00:53:52-08:00 summary: bpo-38524: document implicit and explicit calling of descriptors' __set_name__ (GH-17364) (cherry picked from commit 1bddf890e595a865414645c6041733043c4081f8) Co-authored-by: Florian Dahlitz files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 1703be6e77ad9..ae24adeacb167 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1655,8 +1655,19 @@ class' :attr:`~object.__dict__`. Called at the time the owning class *owner* is created. The descriptor has been assigned to *name*. - .. versionadded:: 3.6 + .. note:: + + ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so + it will need to be called explicitly with the appropriate parameters when a + descriptor is added to a class after initial creation:: + descr = custom_descriptor() + cls.attr = descr + descr.__set_name__(cls, 'attr') + + See :ref:`class-object-creation` for more details. + + .. versionadded:: 3.6 The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module as specifying the class where this object was defined (setting this From webhook-mailer at python.org Wed Nov 27 08:22:11 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Wed, 27 Nov 2019 13:22:11 -0000 Subject: [Python-checkins] bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) Message-ID: https://github.com/python/cpython/commit/ea9835c5d154ab6a54eed627958473b6768b28cc commit: ea9835c5d154ab6a54eed627958473b6768b28cc branch: master author: Inada Naoki committer: GitHub date: 2019-11-27T22:22:06+09:00 summary: bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) SpooledTemporaryFile.rollback() might cause data corruption when it is in text mode. Co-Authored-By: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst M Doc/library/tempfile.rst M Lib/tempfile.py M Lib/test/test_tempfile.py diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index fff7a7a03eb81..a59817c103921 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -105,8 +105,8 @@ The module defines the following user-callable items: causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on - whether binary or text *mode* was specified) or a true file + is either an :class:`io.BytesIO` or :class:`io.TextIOWrapper` object + (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like a normal file. diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 45709cb06cf4e..62875540f8b92 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -633,10 +633,9 @@ def __init__(self, max_size=0, mode='w+b', buffering=-1, if 'b' in mode: self._file = _io.BytesIO() else: - # Setting newline="\n" avoids newline translation; - # this is important because otherwise on Windows we'd - # get double newline translation upon rollover(). - self._file = _io.StringIO(newline="\n") + self._file = _io.TextIOWrapper(_io.BytesIO(), + encoding=encoding, errors=errors, + newline=newline) self._max_size = max_size self._rolled = False self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, @@ -656,8 +655,12 @@ def rollover(self): newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) del self._TemporaryFileArgs - newfile.write(file.getvalue()) - newfile.seek(file.tell(), 0) + pos = file.tell() + if hasattr(newfile, 'buffer'): + newfile.buffer.write(file.detach().getvalue()) + else: + newfile.write(file.getvalue()) + newfile.seek(pos, 0) self._rolled = True diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index f995f6c9bfaf0..232c5dae10fdf 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1114,7 +1114,8 @@ def test_properties(self): def test_text_mode(self): # Creating a SpooledTemporaryFile with a text mode should produce # a file object reading and writing (Unicode) text strings. - f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10) + f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, + encoding="utf-8") f.write("abc\n") f.seek(0) self.assertEqual(f.read(), "abc\n") @@ -1124,9 +1125,9 @@ def test_text_mode(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) - self.assertIsNone(f.errors) + self.assertEqual(f.newlines, os.linesep) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "strict") f.write("xyzzy\n") f.seek(0) @@ -1139,8 +1140,8 @@ def test_text_mode(self): self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) self.assertEqual(f.newlines, os.linesep) - self.assertIsNotNone(f.encoding) - self.assertIsNotNone(f.errors) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "strict") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, @@ -1152,13 +1153,15 @@ def test_text_newline_and_encoding(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) - self.assertIsNone(f.errors) + self.assertIsNotNone(f.newlines) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "ignore") - f.write("\u039B" * 20 + "\r\n") + f.write("\u039C" * 10 + "\r\n") + f.write("\u039D" * 20) f.seek(0) - self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n") + self.assertEqual(f.read(), + "\u039B\r\n" + ("\u039C" * 10) + "\r\n" + ("\u039D" * 20)) self.assertTrue(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) diff --git a/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst new file mode 100644 index 0000000000000..a92b90a495605 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst @@ -0,0 +1,2 @@ +Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file when it is in +text mode. Patch by Serhiy Storchaka. From webhook-mailer at python.org Wed Nov 27 15:22:08 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Wed, 27 Nov 2019 20:22:08 -0000 Subject: [Python-checkins] bpo-38928: Fix versionadded for venv's upgrade_deps function (GH-17404) Message-ID: https://github.com/python/cpython/commit/045d4e243d042638bbbc9479d4f85f6f579ac3ca commit: 045d4e243d042638bbbc9479d4f85f6f579ac3ca branch: master author: Tzu-ping Chung committer: Vinay Sajip date: 2019-11-27T20:21:48Z summary: bpo-38928: Fix versionadded for venv's upgrade_deps function (GH-17404) files: A Misc/NEWS.d/next/Documentation/2019-11-27-17-51-27.bpo-38928.AfgvfO.rst M Doc/library/venv.rst diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index b29fb3ebb60ea..5494c0c878bc5 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -132,7 +132,7 @@ creation according to their needs, the :class:`EnvBuilder` class. .. versionadded:: 3.6 Added the ``prompt`` parameter - .. versionadded:: 3.8 + .. versionadded:: 3.9 Added the ``upgrade_deps`` parameter Creators of third-party virtual environment tools will be free to use the @@ -197,7 +197,7 @@ creation according to their needs, the :class:`EnvBuilder` class. ``setuptools``) in the environment. This is done by shelling out to the ``pip`` executable in the environment. - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. method:: post_setup(context) diff --git a/Misc/NEWS.d/next/Documentation/2019-11-27-17-51-27.bpo-38928.AfgvfO.rst b/Misc/NEWS.d/next/Documentation/2019-11-27-17-51-27.bpo-38928.AfgvfO.rst new file mode 100644 index 0000000000000..952d4a8664d33 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-27-17-51-27.bpo-38928.AfgvfO.rst @@ -0,0 +1,2 @@ +Correct when venv's ``upgrade_dependencies()`` and ``--upgrade-deps`` are +added. From webhook-mailer at python.org Wed Nov 27 15:25:29 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Wed, 27 Nov 2019 20:25:29 -0000 Subject: [Python-checkins] bpo-38927: Use python -m pip to upgrade venv deps (GH-17403) Message-ID: https://github.com/python/cpython/commit/d9aa216d49423d58e192cd7a25016f90fe771ce7 commit: d9aa216d49423d58e192cd7a25016f90fe771ce7 branch: master author: Tzu-ping Chung committer: Vinay Sajip date: 2019-11-27T20:25:23Z summary: bpo-38927: Use python -m pip to upgrade venv deps (GH-17403) I suggest you add `bpo-NNNNN: ` as a prefix for the first commit for future PRs. Thanks! files: A Misc/NEWS.d/next/Library/2019-11-27-17-47-00.bpo-38927.qT7xKY.rst M Lib/test/test_venv.py M Lib/venv/__init__.py diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 0103de8828dd1..741ac109bbc8c 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -141,16 +141,18 @@ def test_prompt(self): def test_upgrade_dependencies(self): builder = venv.EnvBuilder() bin_path = 'Scripts' if sys.platform == 'win32' else 'bin' - pip_exe = 'pip.exe' if sys.platform == 'win32' else 'pip' + python_exe = 'python.exe' if sys.platform == 'win32' else 'python' with tempfile.TemporaryDirectory() as fake_env_dir: def pip_cmd_checker(cmd): self.assertEqual( cmd, [ - os.path.join(fake_env_dir, bin_path, pip_exe), + os.path.join(fake_env_dir, bin_path, python_exe), + '-m', + 'pip', 'install', - '-U', + '--upgrade', 'pip', 'setuptools' ] diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 4ab9cc6d6fb2b..81cb1d13e2163 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -393,10 +393,10 @@ def upgrade_dependencies(self, context): f'Upgrading {CORE_VENV_DEPS} packages in {context.bin_path}' ) if sys.platform == 'win32': - pip_exe = os.path.join(context.bin_path, 'pip.exe') + python_exe = os.path.join(context.bin_path, 'python.exe') else: - pip_exe = os.path.join(context.bin_path, 'pip') - cmd = [pip_exe, 'install', '-U'] + python_exe = os.path.join(context.bin_path, 'python') + cmd = [python_exe, '-m', 'pip', 'install', '--upgrade'] cmd.extend(CORE_VENV_DEPS) subprocess.check_call(cmd) diff --git a/Misc/NEWS.d/next/Library/2019-11-27-17-47-00.bpo-38927.qT7xKY.rst b/Misc/NEWS.d/next/Library/2019-11-27-17-47-00.bpo-38927.qT7xKY.rst new file mode 100644 index 0000000000000..ca6ed63e5ccc1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-27-17-47-00.bpo-38927.qT7xKY.rst @@ -0,0 +1 @@ +Use ``python -m pip`` instead of ``pip`` to upgrade dependencies in venv. From webhook-mailer at python.org Thu Nov 28 00:22:30 2019 From: webhook-mailer at python.org (Tal Einat) Date: Thu, 28 Nov 2019 05:22:30 -0000 Subject: [Python-checkins] bpo-38524: clarify example a bit and improve formatting (GH-17406) Message-ID: https://github.com/python/cpython/commit/02519f75d15b063914a11351da30178ca4ceb54b commit: 02519f75d15b063914a11351da30178ca4ceb54b branch: master author: Tal Einat committer: GitHub date: 2019-11-28T07:22:09+02:00 summary: bpo-38524: clarify example a bit and improve formatting (GH-17406) files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 68098508afbaa..b22ed92ec964d 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1657,13 +1657,16 @@ class' :attr:`~object.__dict__`. .. note:: - ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so - it will need to be called explicitly with the appropriate parameters when a - descriptor is added to a class after initial creation:: + :meth:`__set_name__` is only called implicitly as part of the + :class:`type` constructor, so it will need to be called explicitly with + the appropriate parameters when a descriptor is added to a class after + initial creation:: + class A: + pass descr = custom_descriptor() - cls.attr = descr - descr.__set_name__(cls, 'attr') + A.attr = descr + descr.__set_name__(A, 'attr') See :ref:`class-object-creation` for more details. From webhook-mailer at python.org Thu Nov 28 00:23:18 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 28 Nov 2019 05:23:18 -0000 Subject: [Python-checkins] bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) Message-ID: https://github.com/python/cpython/commit/d21b8e82dda3caf0989bb39bc0e0ce2bfef97081 commit: d21b8e82dda3caf0989bb39bc0e0ce2bfef97081 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-27T21:23:14-08:00 summary: bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) SpooledTemporaryFile.rollback() might cause data corruption when it is in text mode. Co-Authored-By: Serhiy Storchaka (cherry picked from commit ea9835c5d154ab6a54eed627958473b6768b28cc) Co-authored-by: Inada Naoki files: A Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst M Doc/library/tempfile.rst M Lib/tempfile.py M Lib/test/test_tempfile.py diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index fff7a7a03eb81..a59817c103921 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -105,8 +105,8 @@ The module defines the following user-callable items: causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on - whether binary or text *mode* was specified) or a true file + is either an :class:`io.BytesIO` or :class:`io.TextIOWrapper` object + (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like a normal file. diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 45709cb06cf4e..62875540f8b92 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -633,10 +633,9 @@ def __init__(self, max_size=0, mode='w+b', buffering=-1, if 'b' in mode: self._file = _io.BytesIO() else: - # Setting newline="\n" avoids newline translation; - # this is important because otherwise on Windows we'd - # get double newline translation upon rollover(). - self._file = _io.StringIO(newline="\n") + self._file = _io.TextIOWrapper(_io.BytesIO(), + encoding=encoding, errors=errors, + newline=newline) self._max_size = max_size self._rolled = False self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, @@ -656,8 +655,12 @@ def rollover(self): newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) del self._TemporaryFileArgs - newfile.write(file.getvalue()) - newfile.seek(file.tell(), 0) + pos = file.tell() + if hasattr(newfile, 'buffer'): + newfile.buffer.write(file.detach().getvalue()) + else: + newfile.write(file.getvalue()) + newfile.seek(pos, 0) self._rolled = True diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index f995f6c9bfaf0..232c5dae10fdf 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1114,7 +1114,8 @@ def test_properties(self): def test_text_mode(self): # Creating a SpooledTemporaryFile with a text mode should produce # a file object reading and writing (Unicode) text strings. - f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10) + f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, + encoding="utf-8") f.write("abc\n") f.seek(0) self.assertEqual(f.read(), "abc\n") @@ -1124,9 +1125,9 @@ def test_text_mode(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) - self.assertIsNone(f.errors) + self.assertEqual(f.newlines, os.linesep) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "strict") f.write("xyzzy\n") f.seek(0) @@ -1139,8 +1140,8 @@ def test_text_mode(self): self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) self.assertEqual(f.newlines, os.linesep) - self.assertIsNotNone(f.encoding) - self.assertIsNotNone(f.errors) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "strict") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, @@ -1152,13 +1153,15 @@ def test_text_newline_and_encoding(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) - self.assertIsNone(f.errors) + self.assertIsNotNone(f.newlines) + self.assertEqual(f.encoding, "utf-8") + self.assertEqual(f.errors, "ignore") - f.write("\u039B" * 20 + "\r\n") + f.write("\u039C" * 10 + "\r\n") + f.write("\u039D" * 20) f.seek(0) - self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n") + self.assertEqual(f.read(), + "\u039B\r\n" + ("\u039C" * 10) + "\r\n" + ("\u039D" * 20)) self.assertTrue(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) diff --git a/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst new file mode 100644 index 0000000000000..a92b90a495605 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst @@ -0,0 +1,2 @@ +Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file when it is in +text mode. Patch by Serhiy Storchaka. From webhook-mailer at python.org Thu Nov 28 00:24:03 2019 From: webhook-mailer at python.org (Inada Naoki) Date: Thu, 28 Nov 2019 05:24:03 -0000 Subject: [Python-checkins] bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) Message-ID: https://github.com/python/cpython/commit/e65b3fa9f16537d20f5f37c25673ac899fcd7099 commit: e65b3fa9f16537d20f5f37c25673ac899fcd7099 branch: 3.7 author: Inada Naoki committer: GitHub date: 2019-11-28T14:23:58+09:00 summary: bpo-26730: Fix SpooledTemporaryFile data corruption (GH-17400) SpooledTemporaryFile.rollback() might cause data corruption when it is in text mode. Co-Authored-By: Serhiy Storchaka . (cherry picked from commit ea9835c5d154ab6a54eed627958473b6768b28cc) files: A Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst M Doc/library/tempfile.rst M Lib/tempfile.py M Lib/test/test_tempfile.py diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index dd24a1c6f4ffd..00acf4b179237 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -95,8 +95,8 @@ The module defines the following user-callable items: causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on - whether binary or text *mode* was specified) or a true file + is either an :class:`io.BytesIO` or :class:`io.TextIOWrapper` object + (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like a normal file. diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 214322416963c..24f673c64aa8d 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -637,10 +637,8 @@ def __init__(self, max_size=0, mode='w+b', buffering=-1, if 'b' in mode: self._file = _io.BytesIO() else: - # Setting newline="\n" avoids newline translation; - # this is important because otherwise on Windows we'd - # get double newline translation upon rollover(). - self._file = _io.StringIO(newline="\n") + self._file = _io.TextIOWrapper(_io.BytesIO(), + encoding=encoding, newline=newline) self._max_size = max_size self._rolled = False self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, @@ -660,8 +658,12 @@ def rollover(self): newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) del self._TemporaryFileArgs - newfile.write(file.getvalue()) - newfile.seek(file.tell(), 0) + pos = file.tell() + if hasattr(newfile, 'buffer'): + newfile.buffer.write(file.detach().getvalue()) + else: + newfile.write(file.getvalue()) + newfile.seek(pos, 0) self._rolled = True diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 931312831616c..c0464200a3aa3 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1119,7 +1119,8 @@ def test_properties(self): def test_text_mode(self): # Creating a SpooledTemporaryFile with a text mode should produce # a file object reading and writing (Unicode) text strings. - f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10) + f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, + encoding="utf-8") f.write("abc\n") f.seek(0) self.assertEqual(f.read(), "abc\n") @@ -1129,8 +1130,8 @@ def test_text_mode(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) + self.assertEqual(f.newlines, os.linesep) + self.assertEqual(f.encoding, "utf-8") f.write("xyzzy\n") f.seek(0) @@ -1143,7 +1144,7 @@ def test_text_mode(self): self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) self.assertEqual(f.newlines, os.linesep) - self.assertIsNotNone(f.encoding) + self.assertEqual(f.encoding, "utf-8") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, @@ -1154,12 +1155,14 @@ def test_text_newline_and_encoding(self): self.assertFalse(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNone(f.name) - self.assertIsNone(f.newlines) - self.assertIsNone(f.encoding) + self.assertIsNotNone(f.newlines) + self.assertEqual(f.encoding, "utf-8") - f.write("\u039B" * 20 + "\r\n") + f.write("\u039C" * 10 + "\r\n") + f.write("\u039D" * 20) f.seek(0) - self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n") + self.assertEqual(f.read(), + "\u039B\r\n" + ("\u039C" * 10) + "\r\n" + ("\u039D" * 20)) self.assertTrue(f._rolled) self.assertEqual(f.mode, 'w+') self.assertIsNotNone(f.name) diff --git a/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst new file mode 100644 index 0000000000000..a92b90a495605 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-11-27-16-30-02.bpo-26730.56cdBn.rst @@ -0,0 +1,2 @@ +Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file when it is in +text mode. Patch by Serhiy Storchaka. From webhook-mailer at python.org Thu Nov 28 00:28:42 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 28 Nov 2019 05:28:42 -0000 Subject: [Python-checkins] bpo-38524: clarify example a bit and improve formatting (GH-17406) Message-ID: https://github.com/python/cpython/commit/7e9bbbe51e74e5928e6a6c3e70434d824970ef58 commit: 7e9bbbe51e74e5928e6a6c3e70434d824970ef58 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-27T21:28:37-08:00 summary: bpo-38524: clarify example a bit and improve formatting (GH-17406) (cherry picked from commit 02519f75d15b063914a11351da30178ca4ceb54b) Co-authored-by: Tal Einat files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 7a99e1e5220bb..b4f9ddc1194cb 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1643,13 +1643,16 @@ class' :attr:`~object.__dict__`. .. note:: - ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so - it will need to be called explicitly with the appropriate parameters when a - descriptor is added to a class after initial creation:: + :meth:`__set_name__` is only called implicitly as part of the + :class:`type` constructor, so it will need to be called explicitly with + the appropriate parameters when a descriptor is added to a class after + initial creation:: + class A: + pass descr = custom_descriptor() - cls.attr = descr - descr.__set_name__(cls, 'attr') + A.attr = descr + descr.__set_name__(A, 'attr') See :ref:`class-object-creation` for more details. From webhook-mailer at python.org Thu Nov 28 00:29:06 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Thu, 28 Nov 2019 05:29:06 -0000 Subject: [Python-checkins] bpo-38524: clarify example a bit and improve formatting (GH-17406) Message-ID: https://github.com/python/cpython/commit/c0db88f6abbace79644b2aca2290bf41b1a37174 commit: c0db88f6abbace79644b2aca2290bf41b1a37174 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: GitHub date: 2019-11-27T21:29:02-08:00 summary: bpo-38524: clarify example a bit and improve formatting (GH-17406) (cherry picked from commit 02519f75d15b063914a11351da30178ca4ceb54b) Co-authored-by: Tal Einat files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index ae24adeacb167..46d50ad600ff5 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1657,13 +1657,16 @@ class' :attr:`~object.__dict__`. .. note:: - ``__set_name__`` is only called implicitly as part of the ``type`` constructor, so - it will need to be called explicitly with the appropriate parameters when a - descriptor is added to a class after initial creation:: + :meth:`__set_name__` is only called implicitly as part of the + :class:`type` constructor, so it will need to be called explicitly with + the appropriate parameters when a descriptor is added to a class after + initial creation:: + class A: + pass descr = custom_descriptor() - cls.attr = descr - descr.__set_name__(cls, 'attr') + A.attr = descr + descr.__set_name__(A, 'attr') See :ref:`class-object-creation` for more details. From webhook-mailer at python.org Thu Nov 28 10:44:15 2019 From: webhook-mailer at python.org (Vinay Sajip) Date: Thu, 28 Nov 2019 15:44:15 -0000 Subject: [Python-checkins] bpo-38928: Remove upgrade_dependencies() from venv doc (GH-17410) Message-ID: https://github.com/python/cpython/commit/18d8edbbb6626ac9cdf1152a720811beb2230b33 commit: 18d8edbbb6626ac9cdf1152a720811beb2230b33 branch: 3.8 author: Tzu-ping Chung committer: Vinay Sajip date: 2019-11-28T15:44:08Z summary: bpo-38928: Remove upgrade_dependencies() from venv doc (GH-17410) files: M Doc/library/venv.rst diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 3483ef36a2c33..31a3f41e4724c 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -186,14 +186,6 @@ creation according to their needs, the :class:`EnvBuilder` class. Installs activation scripts appropriate to the platform into the virtual environment. - .. method:: upgrade_dependencies(context) - - Upgrades the core venv dependency packages (currently ``pip`` and - ``setuptools``) in the environment. This is done by shelling out to the - ``pip`` executable in the environment. - - .. versionadded:: 3.8 - .. method:: post_setup(context) A placeholder method which can be overridden in third party From webhook-mailer at python.org Thu Nov 28 11:46:31 2019 From: webhook-mailer at python.org (Steve Dower) Date: Thu, 28 Nov 2019 16:46:31 -0000 Subject: [Python-checkins] bpo-38920: Add audit hooks for when sys.excepthook and sys.unraisable hooks are invoked (GH-17392) Message-ID: https://github.com/python/cpython/commit/bea33f5e1db6e4a554919a82894f44568576e979 commit: bea33f5e1db6e4a554919a82894f44568576e979 branch: master author: Steve Dower committer: GitHub date: 2019-11-28T08:46:11-08:00 summary: bpo-38920: Add audit hooks for when sys.excepthook and sys.unraisable hooks are invoked (GH-17392) Also fixes some potential segfaults in unraisable hook handling. files: A Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst M Doc/library/sys.rst M Lib/test/audit-tests.py M Lib/test/test_audit.py M Python/errors.c M Python/pythonrun.c M Python/sysmodule.c diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 2f33445a6f9f5..a824fb95e8ecf 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -36,13 +36,18 @@ always available. .. audit-event:: sys.addaudithook "" sys.addaudithook Raise an auditing event ``sys.addaudithook`` with no arguments. If any - existing hooks raise an exception derived from :class:`Exception`, the + existing hooks raise an exception derived from :class:`RuntimeError`, the new hook will not be added and the exception suppressed. As a result, callers cannot assume that their hook has been added unless they control all existing hooks. .. versionadded:: 3.8 + .. versionchanged:: 3.8.1 + + Exceptions derived from :class:`Exception` but not :class:`RuntimeError` + are no longer suppressed. + .. impl-detail:: When tracing is enabled (see :func:`settrace`), Python hooks are only @@ -308,6 +313,15 @@ always available. before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to ``sys.excepthook``. + .. audit-event:: sys.excepthook hook,type,value,traceback sys.excepthook + + Raise an auditing event ``sys.excepthook`` with arguments ``hook``, + ``type``, ``value``, ``traceback`` when an uncaught exception occurs. + If no hook has been set, ``hook`` may be ``None``. If any hook raises + an exception derived from :class:`RuntimeError` the call to the hook will + be suppressed. Otherwise, the audit hook exception will be reported as + unraisable and ``sys.excepthook`` will be called. + .. seealso:: The :func:`sys.unraisablehook` function handles unraisable exceptions @@ -1540,6 +1554,13 @@ always available. See also :func:`excepthook` which handles uncaught exceptions. + .. audit-event:: sys.unraisablehook hook,unraisable sys.unraisablehook + + Raise an auditing event ``sys.unraisablehook`` with arguments + ``hook``, ``unraisable`` when an exception that cannot be handled occurs. + The ``unraisable`` object is the same as what will be passed to the hook. + If no hook has been set, ``hook`` may be ``None``. + .. versionadded:: 3.8 .. data:: version diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index ddeff22030a4b..ed08612c0417f 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -263,13 +263,50 @@ def trace(frame, event, *args): def test_mmap(): import mmap + with TestHook() as hook: mmap.mmap(-1, 8) assertEqual(hook.seen[0][1][:2], (-1, 8)) +def test_excepthook(): + def excepthook(exc_type, exc_value, exc_tb): + if exc_type is not RuntimeError: + sys.__excepthook__(exc_type, exc_value, exc_tb) + + def hook(event, args): + if event == "sys.excepthook": + if not isinstance(args[2], args[1]): + raise TypeError(f"Expected isinstance({args[2]!r}, " f"{args[1]!r})") + if args[0] != excepthook: + raise ValueError(f"Expected {args[0]} == {excepthook}") + print(event, repr(args[2])) + + sys.addaudithook(hook) + sys.excepthook = excepthook + raise RuntimeError("fatal-error") + + +def test_unraisablehook(): + from _testcapi import write_unraisable_exc + + def unraisablehook(hookargs): + pass + + def hook(event, args): + if event == "sys.unraisablehook": + if args[0] != unraisablehook: + raise ValueError(f"Expected {args[0]} == {unraisablehook}") + print(event, repr(args[1].exc_value), args[1].err_msg) + + sys.addaudithook(hook) + sys.unraisablehook = unraisablehook + write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None) + + if __name__ == "__main__": from test.libregrtest.setup import suppress_msvcrt_asserts + suppress_msvcrt_asserts(False) test = sys.argv[1] diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 41f9fae102231..31a08559273ee 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -24,7 +24,23 @@ def do_test(self, *args): sys.stdout.writelines(p.stdout) sys.stderr.writelines(p.stderr) if p.returncode: - self.fail(''.join(p.stderr)) + self.fail("".join(p.stderr)) + + def run_python(self, *args): + events = [] + with subprocess.Popen( + [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.wait() + sys.stderr.writelines(p.stderr) + return ( + p.returncode, + [line.strip().partition(" ") for line in p.stdout], + "".join(p.stderr), + ) def test_basic(self): self.do_test("test_basic") @@ -36,19 +52,11 @@ def test_block_add_hook_baseexception(self): self.do_test("test_block_add_hook_baseexception") def test_finalize_hooks(self): - events = [] - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, "test_finalize_hooks"], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - for line in p.stdout: - events.append(line.strip().partition(" ")) - sys.stderr.writelines(p.stderr) - if p.returncode: - self.fail(''.join(p.stderr)) + returncode, events, stderr = self.run_python("test_finalize_hooks") + if stderr: + print(stderr, file=sys.stderr) + if returncode: + self.fail(stderr) firstId = events[0][2] self.assertSequenceEqual( @@ -76,6 +84,26 @@ def test_cantrace(self): def test_mmap(self): self.do_test("test_mmap") + def test_excepthook(self): + returncode, events, stderr = self.run_python("test_excepthook") + if not returncode: + self.fail(f"Expected fatal exception\n{stderr}") + + self.assertSequenceEqual( + [("sys.excepthook", " ", "RuntimeError('fatal-error')")], events + ) + + def test_unraisablehook(self): + returncode, events, stderr = self.run_python("test_unraisablehook") + if returncode: + self.fail(stderr) + + self.assertEqual(events[0][0], "sys.unraisablehook") + self.assertEqual( + events[0][2], + "RuntimeError('nonfatal-error') Exception ignored for audit hook test", + ) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst new file mode 100644 index 0000000000000..2e9e443dd999b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst @@ -0,0 +1,2 @@ +Add audit hooks for when :func:`sys.excepthook` and +:func:`sys.unraisablehook` are invoked diff --git a/Python/errors.c b/Python/errors.c index 1783084c336b1..d65707e7f97f5 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1391,43 +1391,53 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) } } + PyObject *hook_args = make_unraisable_hook_args( + tstate, exc_type, exc_value, exc_tb, err_msg, obj); + if (hook_args == NULL) { + err_msg_str = ("Exception ignored on building " + "sys.unraisablehook arguments"); + goto error; + } + _Py_IDENTIFIER(unraisablehook); PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); - if (hook != NULL && hook != Py_None) { - PyObject *hook_args; - - hook_args = make_unraisable_hook_args(tstate, exc_type, exc_value, - exc_tb, err_msg, obj); - if (hook_args != NULL) { - PyObject *res = _PyObject_CallOneArg(hook, hook_args); - Py_DECREF(hook_args); - if (res != NULL) { - Py_DECREF(res); - goto done; - } - - err_msg_str = "Exception ignored in sys.unraisablehook"; - } - else { - err_msg_str = ("Exception ignored on building " - "sys.unraisablehook arguments"); - } + if (hook == NULL) { + Py_DECREF(hook_args); + goto default_hook; + } - Py_XDECREF(err_msg); - err_msg = PyUnicode_FromString(err_msg_str); - if (err_msg == NULL) { - PyErr_Clear(); - } + if (PySys_Audit("sys.unraisablehook", "OO", hook, hook_args) < 0) { + Py_DECREF(hook_args); + err_msg_str = "Exception ignored in audit hook"; + obj = NULL; + goto error; + } - /* sys.unraisablehook failed: log its error using default hook */ - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + if (hook == Py_None) { + Py_DECREF(hook_args); + goto default_hook; + } - obj = hook; + PyObject *res = _PyObject_CallOneArg(hook, hook_args); + Py_DECREF(hook_args); + if (res != NULL) { + Py_DECREF(res); + goto done; } + /* sys.unraisablehook failed: log its error using default hook */ + obj = hook; + err_msg_str = NULL; + +error: + /* err_msg_str and obj have been updated and we have a new exception */ + Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? + err_msg_str : "Exception ignored in sys.unraisablehook")); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + default_hook: /* Call the default unraisable hook (ignore failure) */ (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 77a95ceb94bf0..b68a0b5572a1b 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -695,6 +695,14 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) } } hook = _PySys_GetObjectId(&PyId_excepthook); + if (PySys_Audit("sys.excepthook", "OOOO", hook ? hook : Py_None, + exception, v, tb) < 0) { + if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { + PyErr_Clear(); + goto done; + } + _PyErr_WriteUnraisableMsg("in audit hook", NULL); + } if (hook) { PyObject* stack[3]; PyObject *result; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 30c7e987461b2..78b9d22821fe3 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -323,8 +323,8 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) /* Cannot invoke hooks until we are initialized */ if (runtime->initialized) { if (PySys_Audit("sys.addaudithook", NULL) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { - /* We do not report errors derived from Exception */ + if (_PyErr_ExceptionMatches(tstate, PyExc_RuntimeError)) { + /* We do not report errors derived from RuntimeError */ _PyErr_Clear(tstate); return 0; } From webhook-mailer at python.org Thu Nov 28 11:46:32 2019 From: webhook-mailer at python.org (Steve Dower) Date: Thu, 28 Nov 2019 16:46:32 -0000 Subject: [Python-checkins] bpo-38920: Add audit hooks for when sys.excepthook and sys.unraisablehook are invoked (GH-17392) Message-ID: https://github.com/python/cpython/commit/b74a6f14b94d36fb72b1344663e81776bf450847 commit: b74a6f14b94d36fb72b1344663e81776bf450847 branch: 3.8 author: Steve Dower committer: GitHub date: 2019-11-28T08:46:23-08:00 summary: bpo-38920: Add audit hooks for when sys.excepthook and sys.unraisablehook are invoked (GH-17392) Also fixes some potential segfaults in unraisable hook handling. files: A Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst M Doc/library/sys.rst M Lib/test/audit-tests.py M Lib/test/test_audit.py M Python/errors.c M Python/pythonrun.c M Python/sysmodule.c diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 8d0de479e9cf5..1cf19b8ad6c02 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -36,13 +36,18 @@ always available. .. audit-event:: sys.addaudithook "" sys.addaudithook Raise an auditing event ``sys.addaudithook`` with no arguments. If any - existing hooks raise an exception derived from :class:`Exception`, the + existing hooks raise an exception derived from :class:`RuntimeError`, the new hook will not be added and the exception suppressed. As a result, callers cannot assume that their hook has been added unless they control all existing hooks. .. versionadded:: 3.8 + .. versionchanged:: 3.8.1 + + Exceptions derived from :class:`Exception` but not :class:`RuntimeError` + are no longer suppressed. + .. impl-detail:: When tracing is enabled (see :func:`settrace`), Python hooks are only @@ -308,6 +313,15 @@ always available. before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to ``sys.excepthook``. + .. audit-event:: sys.excepthook hook,type,value,traceback sys.excepthook + + Raise an auditing event ``sys.excepthook`` with arguments ``hook``, + ``type``, ``value``, ``traceback`` when an uncaught exception occurs. + If no hook has been set, ``hook`` may be ``None``. If any hook raises + an exception derived from :class:`RuntimeError` the call to the hook will + be suppressed. Otherwise, the audit hook exception will be reported as + unraisable and ``sys.excepthook`` will be called. + .. seealso:: The :func:`sys.unraisablehook` function handles unraisable exceptions @@ -1563,6 +1577,13 @@ always available. See also :func:`excepthook` which handles uncaught exceptions. + .. audit-event:: sys.unraisablehook hook,unraisable sys.unraisablehook + + Raise an auditing event ``sys.unraisablehook`` with arguments + ``hook``, ``unraisable`` when an exception that cannot be handled occurs. + The ``unraisable`` object is the same as what will be passed to the hook. + If no hook has been set, ``hook`` may be ``None``. + .. versionadded:: 3.8 .. data:: version diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index ddeff22030a4b..ed08612c0417f 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -263,13 +263,50 @@ def trace(frame, event, *args): def test_mmap(): import mmap + with TestHook() as hook: mmap.mmap(-1, 8) assertEqual(hook.seen[0][1][:2], (-1, 8)) +def test_excepthook(): + def excepthook(exc_type, exc_value, exc_tb): + if exc_type is not RuntimeError: + sys.__excepthook__(exc_type, exc_value, exc_tb) + + def hook(event, args): + if event == "sys.excepthook": + if not isinstance(args[2], args[1]): + raise TypeError(f"Expected isinstance({args[2]!r}, " f"{args[1]!r})") + if args[0] != excepthook: + raise ValueError(f"Expected {args[0]} == {excepthook}") + print(event, repr(args[2])) + + sys.addaudithook(hook) + sys.excepthook = excepthook + raise RuntimeError("fatal-error") + + +def test_unraisablehook(): + from _testcapi import write_unraisable_exc + + def unraisablehook(hookargs): + pass + + def hook(event, args): + if event == "sys.unraisablehook": + if args[0] != unraisablehook: + raise ValueError(f"Expected {args[0]} == {unraisablehook}") + print(event, repr(args[1].exc_value), args[1].err_msg) + + sys.addaudithook(hook) + sys.unraisablehook = unraisablehook + write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None) + + if __name__ == "__main__": from test.libregrtest.setup import suppress_msvcrt_asserts + suppress_msvcrt_asserts(False) test = sys.argv[1] diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 41f9fae102231..31a08559273ee 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -24,7 +24,23 @@ def do_test(self, *args): sys.stdout.writelines(p.stdout) sys.stderr.writelines(p.stderr) if p.returncode: - self.fail(''.join(p.stderr)) + self.fail("".join(p.stderr)) + + def run_python(self, *args): + events = [] + with subprocess.Popen( + [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.wait() + sys.stderr.writelines(p.stderr) + return ( + p.returncode, + [line.strip().partition(" ") for line in p.stdout], + "".join(p.stderr), + ) def test_basic(self): self.do_test("test_basic") @@ -36,19 +52,11 @@ def test_block_add_hook_baseexception(self): self.do_test("test_block_add_hook_baseexception") def test_finalize_hooks(self): - events = [] - with subprocess.Popen( - [sys.executable, "-X utf8", AUDIT_TESTS_PY, "test_finalize_hooks"], - encoding="utf-8", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) as p: - p.wait() - for line in p.stdout: - events.append(line.strip().partition(" ")) - sys.stderr.writelines(p.stderr) - if p.returncode: - self.fail(''.join(p.stderr)) + returncode, events, stderr = self.run_python("test_finalize_hooks") + if stderr: + print(stderr, file=sys.stderr) + if returncode: + self.fail(stderr) firstId = events[0][2] self.assertSequenceEqual( @@ -76,6 +84,26 @@ def test_cantrace(self): def test_mmap(self): self.do_test("test_mmap") + def test_excepthook(self): + returncode, events, stderr = self.run_python("test_excepthook") + if not returncode: + self.fail(f"Expected fatal exception\n{stderr}") + + self.assertSequenceEqual( + [("sys.excepthook", " ", "RuntimeError('fatal-error')")], events + ) + + def test_unraisablehook(self): + returncode, events, stderr = self.run_python("test_unraisablehook") + if returncode: + self.fail(stderr) + + self.assertEqual(events[0][0], "sys.unraisablehook") + self.assertEqual( + events[0][2], + "RuntimeError('nonfatal-error') Exception ignored for audit hook test", + ) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst new file mode 100644 index 0000000000000..2e9e443dd999b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-26-09-16-47.bpo-38920.Vx__sT.rst @@ -0,0 +1,2 @@ +Add audit hooks for when :func:`sys.excepthook` and +:func:`sys.unraisablehook` are invoked diff --git a/Python/errors.c b/Python/errors.c index 8a94afdd8c410..197d9779b390c 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1367,44 +1367,54 @@ _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) } } + PyObject *hook_args = make_unraisable_hook_args( + tstate, exc_type, exc_value, exc_tb, err_msg, obj); + if (hook_args == NULL) { + err_msg_str = ("Exception ignored on building " + "sys.unraisablehook arguments"); + goto error; + } + _Py_IDENTIFIER(unraisablehook); PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); - if (hook != NULL && hook != Py_None) { - PyObject *hook_args; - - hook_args = make_unraisable_hook_args(tstate, exc_type, exc_value, - exc_tb, err_msg, obj); - if (hook_args != NULL) { - PyObject *args[1] = {hook_args}; - PyObject *res = _PyObject_FastCall(hook, args, 1); - Py_DECREF(hook_args); - if (res != NULL) { - Py_DECREF(res); - goto done; - } - - err_msg_str = "Exception ignored in sys.unraisablehook"; - } - else { - err_msg_str = ("Exception ignored on building " - "sys.unraisablehook arguments"); - } + if (hook == NULL) { + Py_DECREF(hook_args); + goto default_hook; + } - Py_XDECREF(err_msg); - err_msg = PyUnicode_FromString(err_msg_str); - if (err_msg == NULL) { - PyErr_Clear(); - } + if (PySys_Audit("sys.unraisablehook", "OO", hook, hook_args) < 0) { + Py_DECREF(hook_args); + err_msg_str = "Exception ignored in audit hook"; + obj = NULL; + goto error; + } - /* sys.unraisablehook failed: log its error using default hook */ - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + if (hook == Py_None) { + Py_DECREF(hook_args); + goto default_hook; + } - obj = hook; + PyObject *args[1] = {hook_args}; + PyObject *res = _PyObject_FastCall(hook, args, 1); + Py_DECREF(hook_args); + if (res != NULL) { + Py_DECREF(res); + goto done; } + /* sys.unraisablehook failed: log its error using default hook */ + obj = hook; + err_msg_str = NULL; + +error: + /* err_msg_str and obj have been updated and we have a new exception */ + Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ? + err_msg_str : "Exception ignored in sys.unraisablehook")); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + default_hook: /* Call the default unraisable hook (ignore failure) */ (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, diff --git a/Python/pythonrun.c b/Python/pythonrun.c index c9afa8f8baaf8..a7da143077a7a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -695,6 +695,14 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) } } hook = _PySys_GetObjectId(&PyId_excepthook); + if (PySys_Audit("sys.excepthook", "OOOO", hook ? hook : Py_None, + exception, v, tb) < 0) { + if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { + PyErr_Clear(); + goto done; + } + _PyErr_WriteUnraisableMsg("in audit hook", NULL); + } if (hook) { PyObject* stack[3]; PyObject *result; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 5b0fb813b4566..1255665d024c3 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -293,8 +293,8 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) /* Cannot invoke hooks until we are initialized */ if (Py_IsInitialized()) { if (PySys_Audit("sys.addaudithook", NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_Exception)) { - /* We do not report errors derived from Exception */ + if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { + /* We do not report errors derived from RuntimeError */ PyErr_Clear(); return 0; } From webhook-mailer at python.org Thu Nov 28 23:48:03 2019 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 29 Nov 2019 04:48:03 -0000 Subject: [Python-checkins] [3.8] Added missing coma after end of list in subprocess.rst (GH-17389) Message-ID: https://github.com/python/cpython/commit/305189ecdc8322c22879a04564cad5989f937462 commit: 305189ecdc8322c22879a04564cad5989f937462 branch: 3.8 author: Jules Lasne (jlasne) committer: Benjamin Peterson date: 2019-11-28T22:47:45-06:00 summary: [3.8] Added missing coma after end of list in subprocess.rst (GH-17389) (cherry picked from commit f25875af425a3480e557aaedf49c3bb867bcbd5d) files: M Doc/library/subprocess.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 954e0fec11828..ea12cd133a6ff 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -596,7 +596,7 @@ functions. Popen and the other functions in this module that use it raise an :ref:`auditing event ` ``subprocess.Popen`` with arguments - ``executable``, ``args``, ``cwd``, ``env``. The value for ``args`` + ``executable``, ``args``, ``cwd``, and ``env``. The value for ``args`` may be a single string or a list of strings, depending on platform. .. versionchanged:: 3.2 From webhook-mailer at python.org Fri Nov 29 18:37:16 2019 From: webhook-mailer at python.org (Miss Islington (bot)) Date: Fri, 29 Nov 2019 23:37:16 -0000 Subject: [Python-checkins] Fix old mention of virtualenv (GH-17417) Message-ID: https://github.com/python/cpython/commit/1df65f7c6c00dfae9286c7a58e1b3803e3af33e5 commit: 1df65f7c6c00dfae9286c7a58e1b3803e3af33e5 branch: master author: Brett Cannon <54418+brettcannon at users.noreply.github.com> committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> date: 2019-11-29T15:37:08-08:00 summary: Fix old mention of virtualenv (GH-17417) Automerge-Triggered-By: @brettcannon files: M Lib/venv/scripts/posix/activate.fish diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index d213b9060a687..cb1ba1c301ede 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -1,7 +1,7 @@ # This file must be used with "source /bin/activate.fish" *from fish* # (http://fishshell.org); you cannot run it directly. -function deactivate -d "Exit virtualenv and return to normal shell environment" +function deactivate -d "Exit virtual environment and return to normal shell environment" # reset old environment variables if test -n "$_OLD_VIRTUAL_PATH" set -gx PATH $_OLD_VIRTUAL_PATH From webhook-mailer at python.org Sat Nov 30 03:30:54 2019 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 30 Nov 2019 08:30:54 -0000 Subject: [Python-checkins] bpo-37523: Raise ValueError for I/O operations on a closed zipfile.ZipExtFile. (GH-14658) Message-ID: https://github.com/python/cpython/commit/8d62df60d8733d0fa9aee14ef746d0009a7a9726 commit: 8d62df60d8733d0fa9aee14ef746d0009a7a9726 branch: master author: Daniel Hillier committer: Serhiy Storchaka date: 2019-11-30T10:30:47+02:00 summary: bpo-37523: Raise ValueError for I/O operations on a closed zipfile.ZipExtFile. (GH-14658) Raises ValueError when calling the following on a closed zipfile.ZipExtFile: read, readable, seek, seekable, tell. files: A Misc/NEWS.d/next/Library/2019-10-02-02-55-37.bpo-37523.GguwJ6.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 1e1854be7109b..66f05ac1f3aef 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -571,6 +571,20 @@ def test_write_default_name(self): with open(TESTFN, "rb") as f: self.assertEqual(zipfp.read(TESTFN), f.read()) + def test_io_on_closed_zipextfile(self): + fname = "somefile.txt" + with zipfile.ZipFile(TESTFN2, mode="w") as zipfp: + zipfp.writestr(fname, "bogus") + + with zipfile.ZipFile(TESTFN2, mode="r") as zipfp: + with zipfp.open(fname) as fid: + fid.close() + self.assertRaises(ValueError, fid.read) + self.assertRaises(ValueError, fid.seek, 0) + self.assertRaises(ValueError, fid.tell) + self.assertRaises(ValueError, fid.readable) + self.assertRaises(ValueError, fid.seekable) + def test_write_to_readonly(self): """Check that trying to call write() on a readonly ZipFile object raises a ValueError.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py index b0afb9da942b1..e1d07f2a5237b 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -889,12 +889,16 @@ def peek(self, n=1): return self._readbuffer[self._offset: self._offset + 512] def readable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return True def read(self, n=-1): """Read and return up to n bytes. If the argument is omitted, None, or negative, data is read and returned until EOF is reached. """ + if self.closed: + raise ValueError("read from closed file.") if n is None or n < 0: buf = self._readbuffer[self._offset:] self._readbuffer = b'' @@ -1031,9 +1035,13 @@ def close(self): super().close() def seekable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") return self._seekable def seek(self, offset, whence=0): + if self.closed: + raise ValueError("seek on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") curr_pos = self.tell() @@ -1082,6 +1090,8 @@ def seek(self, offset, whence=0): return self.tell() def tell(self): + if self.closed: + raise ValueError("tell on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") filepos = self._orig_file_size - self._left - len(self._readbuffer) + self._offset diff --git a/Misc/NEWS.d/next/Library/2019-10-02-02-55-37.bpo-37523.GguwJ6.rst b/Misc/NEWS.d/next/Library/2019-10-02-02-55-37.bpo-37523.GguwJ6.rst new file mode 100644 index 0000000000000..5711969ff38cf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-10-02-02-55-37.bpo-37523.GguwJ6.rst @@ -0,0 +1 @@ +Change :class:`zipfile.ZipExtFile` to raise ``ValueError`` when trying to access the underlying file object after it has been closed. This new behavior is consistent with how accessing closed files is handled in other parts of Python. \ No newline at end of file From webhook-mailer at python.org Tue Nov 19 03:12:50 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 19 Nov 2019 08:12:50 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: bpo-22367: Update test_fcntl.py for spawn process mode (#17154) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/9960230f76eb555d6dfbe8a324efed35610c= 85f9 commit: 9960230f76eb555d6dfbe8a324efed35610c85f9 branch: master author: Dong-hee Na committer: =C5=81ukasz Langa date: 2019-11-19T09:12:42+01:00 summary: bpo-22367: Update test_fcntl.py for spawn process mode (#17154) files: M Lib/test/test_fcntl.py diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index 9d1be28c6d399..9ab68c67241f4 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -51,6 +51,21 @@ def __init__(self, fn): def fileno(self): return self.fn =20 +def try_lockf_on_other_process_fail(fname, cmd): + f =3D open(fname, 'wb+') + try: + fcntl.lockf(f, cmd) + except BlockingIOError: + pass + finally: + f.close() + +def try_lockf_on_other_process(fname, cmd): + f =3D open(fname, 'wb+') + fcntl.lockf(f, cmd) + fcntl.lockf(f, fcntl.LOCK_UN) + f.close() + class TestFcntl(unittest.TestCase): =20 def setUp(self): @@ -138,28 +153,23 @@ def test_flock(self): self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) =20 + @unittest.skipIf(platform.system() =3D=3D "AIX", "AIX returns Permission= Error") def test_lockf_exclusive(self): self.f =3D open(TESTFN, 'wb+') cmd =3D fcntl.LOCK_EX | fcntl.LOCK_NB - def try_lockf_on_other_process(): - self.assertRaises(BlockingIOError, fcntl.lockf, self.f, cmd) - fcntl.lockf(self.f, cmd) - p =3D Process(target=3Dtry_lockf_on_other_process) + p =3D Process(target=3Dtry_lockf_on_other_process_fail, args=3D(TEST= FN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) self.assertEqual(p.exitcode, 0) =20 + @unittest.skipIf(platform.system() =3D=3D "AIX", "AIX returns Permission= Error") def test_lockf_share(self): self.f =3D open(TESTFN, 'wb+') cmd =3D fcntl.LOCK_SH | fcntl.LOCK_NB - def try_lockf_on_other_process(): - fcntl.lockf(self.f, cmd) - fcntl.lockf(self.f, fcntl.LOCK_UN) - fcntl.lockf(self.f, cmd) - p =3D Process(target=3Dtry_lockf_on_other_process) + p =3D Process(target=3Dtry_lockf_on_other_process, args=3D(TESTFN, c= md)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) From webhook-mailer at python.org Tue Nov 19 03:16:51 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Tue, 19 Nov 2019 08:16:51 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: bpo-21767: explicitly mention abc support in functools.singledispatch docs (#17171) Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/24555ce2f969bd69517011d23aaf8cc48109= 0211 commit: 24555ce2f969bd69517011d23aaf8cc481090211 branch: master author: Batuhan Ta=C5=9Fkaya <47358913+isidentical at users.noreply.github.com> committer: =C5=81ukasz Langa date: 2019-11-19T09:16:46+01:00 summary: bpo-21767: explicitly mention abc support in functools.singledispatch docs (#= 17171) files: A Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos.rst M Doc/library/functools.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index cedc3ad5ec0a6..bb7aac42daca7 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -423,6 +423,20 @@ The :mod:`functools` module defines the following functi= ons: for the base ``object`` type, which means it is used if no better implementation is found. =20 + If an implementation registered to :term:`abstract base class`, virtual + subclasses will be dispatched to that implementation:: + + >>> from collections.abc import Mapping + >>> @fun.register + ... def _(arg: Mapping, verbose=3DFalse): + ... if verbose: + ... print("Keys & Values") + ... for key, value in arg.items(): + ... print(key, "=3D>", value) + ... + >>> fun({"a": "b"}) + a =3D> b + To check which implementation will the generic function choose for a given type, use the ``dispatch()`` attribute:: =20 diff --git a/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3= Dos.rst b/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos= .rst new file mode 100644 index 0000000000000..1e2a45e1113cf --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos.rst @@ -0,0 +1 @@ +Explicitly mention abc support in functools.singledispatch From webhook-mailer at python.org Tue Nov 19 20:07:47 2019 From: webhook-mailer at python.org (=?utf-8?q?=C5=81ukasz?= Langa) Date: Wed, 20 Nov 2019 01:07:47 -0000 Subject: [Python-checkins] (no subject) Message-ID: To: python-checkins at python.org Subject: Python 3.9.0a1 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 https://github.com/python/cpython/commit/fd757083df79c21eee862e8d89aeefefe45f= 64a0 commit: fd757083df79c21eee862e8d89aeefefe45f64a0 branch: master author: =C5=81ukasz Langa committer: =C5=81ukasz Langa date: 2019-11-19T12:17:21+01:00 summary: Python 3.9.0a1 files: A Misc/NEWS.d/3.9.0a1.rst D Misc/NEWS.d/next/Build/2019-03-06-18-55-10.bpo-36210.fup9H2.rst D Misc/NEWS.d/next/Build/2019-03-19-22-07-37.bpo-25361.XO9Bfr.rst D Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst D Misc/NEWS.d/next/Build/2019-07-01-14-39-40.bpo-37468.trbQ-_.rst D Misc/NEWS.d/next/Build/2019-07-11-01-28-24.bpo-36044.gIgfiJ.rst D Misc/NEWS.d/next/Build/2019-07-29-11-36-16.bpo-37707.Sm-dGk.rst D Misc/NEWS.d/next/Build/2019-07-30-16-26-11.bpo-37725.MkG1TT.rst D Misc/NEWS.d/next/Build/2019-08-24-00-29-40.bpo-37936.QrORqA.rst D Misc/NEWS.d/next/Build/2019-08-24-17-39-09.bpo-37760.f3jXuH.rst D Misc/NEWS.d/next/Build/2019-09-10-00-54-48.bpo-37936.E7XEwu.rst D Misc/NEWS.d/next/Build/2019-09-13-14-12-36.bpo-36002.Bcl4oe.rst D Misc/NEWS.d/next/Build/2019-09-28-02-37-11.bpo-38301.123456.rst D Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst D Misc/NEWS.d/next/Build/2019-10-13-16-18-24.bpo-38468.buCO84.rst D Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst D Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst D Misc/NEWS.d/next/C API/2018-08-04-00-59-44.bpo-34331.iaUkmU.rst D Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst D Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst D Misc/NEWS.d/next/C API/2019-06-07-14-03-52.bpo-37194.uck7MD.rst D Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst D Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst D Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst D Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst D Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst D Misc/NEWS.d/next/C API/2019-07-02-15-42-37.bpo-37483.vftT4f.rst D Misc/NEWS.d/next/C API/2019-07-06-23-56-47.bpo-21120.lXHqlT.rst D Misc/NEWS.d/next/C API/2019-07-07-10-37-07.bpo-37207.SlVNky.rst D Misc/NEWS.d/next/C API/2019-07-10-12-27-28.bpo-37540.E8Z773.rst D Misc/NEWS.d/next/C API/2019-07-16-11-02-00.bpo-37151.YKfuNA.rst D Misc/NEWS.d/next/C API/2019-07-17-09-50-50.bpo-29548.5wIptQ.rst D Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst D Misc/NEWS.d/next/C API/2019-08-17-13-50-21.bpo-37879.CZeUem.rst D Misc/NEWS.d/next/C API/2019-08-23-11-35-55.bpo-37926.hnI5IQ.rst D Misc/NEWS.d/next/C API/2019-08-23-18-45-11.bpo-36763.q3Kh8Z.rst D Misc/NEWS.d/next/C API/2019-09-05-14-17-21.bpo-15088.plt8Em.rst D Misc/NEWS.d/next/C API/2019-09-13-01-24-47.bpo-38140.y59qaO.rst D Misc/NEWS.d/next/C API/2019-09-19-18-26-29.bpo-38205.Db1OJL.rst D Misc/NEWS.d/next/C API/2019-09-20-17-22-41.bpo-38234.ZbquVK.rst D Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst D Misc/NEWS.d/next/C API/2019-09-30-16-53-30.bpo-38303.YoIs0M.rst D Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst D Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst D Misc/NEWS.d/next/C API/2019-10-08-01-23-24.bpo-38395.MJ6Ey9.rst D Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst D Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst D Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst D Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst D Misc/NEWS.d/next/Core and Builtins/2018-06-07-01-01-20.bpo-30773.C31rVE.rst D Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-27575.mMYgzv.rst D Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-19072.Gc59GS.rst D Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO.rst D Misc/NEWS.d/next/Core and Builtins/2019-02-15-20-42-36.bpo-20523.rRLrvr.rst D Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556.o9kfpu.rst D Misc/NEWS.d/next/Core and Builtins/2019-05-06-09-59-31.bpo-36781.uocWt6.rst D Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974.wdzzym.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922.EMZ3TF.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-06-20-52-38.bpo-15913.5Sg5cv.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-11-12-59-38.bpo-36974.bVYmSA.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-13-12-55-38.bpo-20443.bQWAxg.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316.LytDX_.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224.FHWPGv.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-18-17-53-06.bpo-37330.wAvHmz.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214.hIiHeD.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-23-00-26-30.bpo-37348.pp8P-x.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-24-21-53-52.bpo-37388.0XTZmW.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-25-01-45-06.bpo-37392.J3JhIx.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-26-17-27-26.bpo-37414.o6Lnbc.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417.VsZeHL.rst D Misc/NEWS.d/next/Core and Builtins/2019-06-27-15-01-14.bpo-37433.amNGqr.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-10-20-33-53.bpo-37543.EvI19D.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-14-23-57-27.bpo-37593.yHSTwH.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-18-11-50-49.bpo-37619.X6Lulo.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-20-22-34-42.bpo-37444.UOd3Xs.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-22-11-05-05.bpo-37648.6TY2L-.rst D Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340.5ktLEg.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-01-10-45-51.bpo-34880.u_x_CG.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-02-15-01-33.bpo-36311.uY5vt-.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-04-12-24-18.bpo-36279.8Zy7jZ.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-05-14-22-59.bpo-37757.lRv5HX.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-06-23-39-05.bpo-37409.1qwzn2.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-09-18-28-57.bpo-37802.pKxcAW.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-15-12-48-36.bpo-20490.-hXeEn.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-17-18-41-59.bpo-37830.fNfMbz.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-20-04-36-37.bpo-37751.CSFzUd.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-23-22-46-25.bpo-37812.vsWZwS.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-26-04-09-57.bpo-37947.mzAQtB.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-27-21-21-36.bpo-37966.5OBLez.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-29-01-55-38.bpo-8425.FTq4A8.rst D Misc/NEWS.d/next/Core and Builtins/2019-08-31-11-13-25.bpo-37994.Rj6S4j.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-02-16-17-42.bpo-36946._lAuSR.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-02-20-00-31.bpo-38005.e7VsTA.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-44-17.bpo-38071.bLwkBJ.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-00-42.bpo-38072.Y1xpDO.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-59-50.bpo-38075.N8OZKF.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-09-16-36-37.bpo-38076.C5dVBl.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-10-02.bpo-38113.yZXC3P.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-12-00-14-01.bpo-38124.n6E0H7.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-12-19-50-01.bpo-38013.I7btD0.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-20-19-06-23.bpo-38236.eQ0Tmj.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-22-13-56-18.bpo-38219.rFl7JD.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-24-05-32-27.bpo-11410.vS182p.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-24-18-45-46.bpo-36871.p47knk.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-28-22-54-25.bpo-38310.YDTbEo.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-30-00-56-21.bpo-38317.pmqlIQ.rst D Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006.UYlJum.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-01-12-46-30.bpo-37474.cB3se1.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-05-19-36-16.bpo-38402.EZuzgK.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-06-15-01-57.bpo-38210.Xgc6F_.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-07-22-51-39.bpo-38392.KaXXps.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-09-16-50-52.bpo-38379.oz5qZx.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-10-01-41-02.bpo-38379._q4dhn.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-10-20-42-09.bpo-38437.z_0mZp.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-13-23-41-38.bpo-38469.9kmuQj.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-19-12-44-13.bpo-38465.V1L8c4.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525.Vty1cA.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535.ESMkVN.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029.AmRMEF.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-25-25.bpo-38640.4sAFh5.rst D Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO.rst D Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk.rst D Misc/NEWS.d/next/Documentation/2018-06-02-12-55-23.bpo-25237.m8-JMu.rst D Misc/NEWS.d/next/Documentation/2018-07-31-15-38-26.bpo-34293.yHupAL.rst D Misc/NEWS.d/next/Documentation/2018-10-26-18-10-29.bpo-33944.V1YeOA.rst D Misc/NEWS.d/next/Documentation/2019-01-21-14-30-59.bpo-35803.yae6Lq.rst D Misc/NEWS.d/next/Documentation/2019-02-14-07-12-48.bpo-23460.Iqiqtm.rst D Misc/NEWS.d/next/Documentation/2019-04-02-19-23-00.bpo-36487.Jg6-MG.rst D Misc/NEWS.d/next/Documentation/2019-05-18-16-25-44.bpo-36960.xEKHXj.rst D Misc/NEWS.d/next/Documentation/2019-05-22-04-30-07.bpo-37004.BRgxrt.rst D Misc/NEWS.d/next/Documentation/2019-06-04-09-29-00.bpo-36260.WrGuc-.rst D Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst D Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst D Misc/NEWS.d/next/Documentation/2019-07-06-02-19-02.bpo-37149.NumHn3.rst D Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst D Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst D Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst D Misc/NEWS.d/next/Documentation/2019-07-13-12-43-01.bpo-30088.CIcBjy.rst D Misc/NEWS.d/next/Documentation/2019-07-13-12-58-20.bpo-37284.rP8WpB.rst D Misc/NEWS.d/next/Documentation/2019-07-16-14-48-12.bpo-37256.qJTrBb.rst D Misc/NEWS.d/next/Documentation/2019-07-25-10-30-32.bpo-32910.caLLAe.rst D Misc/NEWS.d/next/Documentation/2019-07-31-11-40-06.bpo-37726.h-3o9a.rst D Misc/NEWS.d/next/Documentation/2019-08-04-19-20-58.bpo-37759.EHRF4i.rst D Misc/NEWS.d/next/Documentation/2019-08-16-20-01-10.bpo-37878.MvA6rZ.rst D Misc/NEWS.d/next/Documentation/2019-08-24-12-59-06.bpo-37937.F7fHbt.rst D Misc/NEWS.d/next/Documentation/2019-08-27-01-14-59.bpo-12707.Yj3_7_.rst D Misc/NEWS.d/next/Documentation/2019-08-29-10-40-05.bpo-37979.TAUx_E.rst D Misc/NEWS.d/next/Documentation/2019-08-29-14-38-01.bpo-37977.pML-UI.rst D Misc/NEWS.d/next/Documentation/2019-09-05-14-47-51.bpo-36797.KN9Ga5.rst D Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst D Misc/NEWS.d/next/Documentation/2019-09-07-19-09-01.bpo-38053.lttibE.rst D Misc/NEWS.d/next/Documentation/2019-09-27-23-37-41.bpo-38294.go_jFf.rst D Misc/NEWS.d/next/Documentation/2019-10-26-13-19-07.bpo-38592.Y96BYO.rst D Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst D Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst D Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst D Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos.rst D Misc/NEWS.d/next/IDLE/2019-03-21-08-35-00.bpo-36390.OdDCGk.rst D Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst D Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst D Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst D Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst D Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst D Misc/NEWS.d/next/IDLE/2019-06-13-01-07-20.bpo-17535.K8i2St.rst D Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst D Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst D Misc/NEWS.d/next/IDLE/2019-07-03-22-47-44.bpo-27452.nePPLi.rst D Misc/NEWS.d/next/IDLE/2019-07-11-00-05-31.bpo-37530.AuyCyD.rst D Misc/NEWS.d/next/IDLE/2019-07-18-10-11-36.bpo-33610.xYqMLg.rst D Misc/NEWS.d/next/IDLE/2019-07-20-23-33-53.bpo-37627.dQhUNB.rst D Misc/NEWS.d/next/IDLE/2019-07-26-17-51-13.bpo-37628.kX4AUF.rst D Misc/NEWS.d/next/IDLE/2019-07-27-15-14-20.bpo-37692.TRHGjD.rst D Misc/NEWS.d/next/IDLE/2019-08-04-15-27-50.bpo-37748.0vf6pg.rst D Misc/NEWS.d/next/IDLE/2019-08-04-17-10-01.bpo-36419.TJZqOc.rst D Misc/NEWS.d/next/IDLE/2019-08-14-09-43-15.bpo-37849.-bcYF3.rst D Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst D Misc/NEWS.d/next/IDLE/2019-08-24-22-00-33.bpo-37929.jb7523.rst D Misc/NEWS.d/next/IDLE/2019-08-26-00-41-53.bpo-37824.YY5jAI.rst D Misc/NEWS.d/next/IDLE/2019-09-01-10-22-55.bpo-35771.tdbmbP.rst D Misc/NEWS.d/next/IDLE/2019-09-05-23-12-13.bpo-38041.nxmGGK.rst D Misc/NEWS.d/next/IDLE/2019-09-09-22-08-36.bpo-38077.Mzpfe2.rst D Misc/NEWS.d/next/IDLE/2019-09-16-15-04-29.bpo-38183.eudCN1.rst D Misc/NEWS.d/next/IDLE/2019-09-17-01-28-56.bpo-35379.yAECDr.rst D Misc/NEWS.d/next/IDLE/2019-10-04-18-03-09.bpo-36698.BKcmom.rst D Misc/NEWS.d/next/IDLE/2019-10-26-18-16-24.bpo-38598.6kH9FY.rst D Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst D Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst D Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst D Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst D Misc/NEWS.d/next/Library/2018-02-13-12-25-43.bpo-32820.0stF0u.rst D Misc/NEWS.d/next/Library/2018-02-13-17-58-30.bpo-32689.a-3SnH.rst D Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst D Misc/NEWS.d/next/Library/2018-06-17-21-02-25.bpo-32498.La3TZz.rst D Misc/NEWS.d/next/Library/2018-07-14-13-48-56.bpo-30618.T5AUF6.rst D Misc/NEWS.d/next/Library/2018-08-04-12-26-11.bpo-28009.4JcHZb.rst D Misc/NEWS.d/next/Library/2018-08-27-15-44-50.bpo-34519.cPlH1h.rst D Misc/NEWS.d/next/Library/2018-09-21-13-23-29.bpo-34749.B0k819.rst D Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst D Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst D Misc/NEWS.d/next/Library/2018-11-19-10-23-58.bpo-25988.6o7gGK.rst D Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst D Misc/NEWS.d/next/Library/2019-01-09-16-18-52.bpo-8538.PfVZia.rst D Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst D Misc/NEWS.d/next/Library/2019-01-25-17-12-17.bpo-35800.MCGJdQ.rst D Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst D Misc/NEWS.d/next/Library/2019-02-19-17-32-45.bpo-36046.fX9OPj.rst D Misc/NEWS.d/next/Library/2019-03-09-16-04-12.bpo-36250.tSK4N1.rst D Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst D Misc/NEWS.d/next/Library/2019-03-23-16-42-46.bpo-36409.ZYVKao.rst D Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst D Misc/NEWS.d/next/Library/2019-04-08-13-00-13.bpo-36564._n67m_.rst D Misc/NEWS.d/next/Library/2019-04-28-10-34-19.bpo-32424.eqNPhM.rst D Misc/NEWS.d/next/Library/2019-05-07-17-42-36.bpo-36582.L_dxR6.rst D Misc/NEWS.d/next/Library/2019-05-07-19-25-55.bpo-31783.lgLo69.rst D Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst D Misc/NEWS.d/next/Library/2019-05-12-12-58-37.bpo-36871.6xiEHZ.rst D Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst D Misc/NEWS.d/next/Library/2019-05-17-16-50-02.bpo-31904.4a5ggm.rst D Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst D Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst D Misc/NEWS.d/next/Library/2019-05-22-04-52-35.bpo-25068.vR_rC-.rst D Misc/NEWS.d/next/Library/2019-05-26-16-34-53.bpo-31163.21A802.rst D Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst D Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst D Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst D Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst D Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst D Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst D Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst D Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst D Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst D Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst D Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst D Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst D Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst D Misc/NEWS.d/next/Library/2019-06-08-23-26-58.bpo-12144.Z7mz-q.rst D Misc/NEWS.d/next/Library/2019-06-09-17-22-33.bpo-37111.2I0z2k.rst D Misc/NEWS.d/next/Library/2019-06-09-22-25-03.bpo-37206.2WBg4q.rst D Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst D Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst D Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst D Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst D Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst D Misc/NEWS.d/next/Library/2019-06-12-08-56-22.bpo-21872.V9QGGN.rst D Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst D Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst D Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst D Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst D Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst D Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst D Misc/NEWS.d/next/Library/2019-06-17-10-03-52.bpo-37312.qKvBfF.rst D Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst D Misc/NEWS.d/next/Library/2019-06-17-22-10-37.bpo-37320.ffieYa.rst D Misc/NEWS.d/next/Library/2019-06-18-13-59-55.bpo-37305.fGzWlP.rst D Misc/NEWS.d/next/Library/2019-06-18-15-31-33.bpo-37328.2PW1-l.rst D Misc/NEWS.d/next/Library/2019-06-18-16-29-31.bpo-37085.GeYaD6.rst D Misc/NEWS.d/next/Library/2019-06-19-10-35-53.bpo-37163.9pPg2F.rst D Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst D Misc/NEWS.d/next/Library/2019-06-21-14-54-02.bpo-37358.RsASpn.rst D Misc/NEWS.d/next/Library/2019-06-22-08-51-44.bpo-37345.o8XABX.rst D Misc/NEWS.d/next/Library/2019-06-22-12-30-00.bpo-37372.kIKqZ6.rst D Misc/NEWS.d/next/Library/2019-06-22-22-00-35.bpo-37212.Zhv-tq.rst D Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst D Misc/NEWS.d/next/Library/2019-06-24-11-26-34.bpo-37376.SwSUQ4.rst D Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst D Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst D Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst D Misc/NEWS.d/next/Library/2019-06-26-03-00-06.bpo-37406.uovkpq.rst D Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst D Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst D Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst D Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst D Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst D Misc/NEWS.d/next/Library/2019-07-02-12-43-57.bpo-37479.O53a5S.rst D Misc/NEWS.d/next/Library/2019-07-02-13-08-30.bpo-37481.hd5k09.rst D Misc/NEWS.d/next/Library/2019-07-03-12-47-52.bpo-37421.gR5hC8.rst D Misc/NEWS.d/next/Library/2019-07-04-13-00-20.bpo-37424.0i1MR-.rst D Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst D Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst D Misc/NEWS.d/next/Library/2019-07-08-03-15-04.bpo-37502.qZGC4g.rst D Misc/NEWS.d/next/Library/2019-07-09-05-44-39.bpo-36993.4javqu.rst D Misc/NEWS.d/next/Library/2019-07-09-11-20-21.bpo-37482.auzvev.rst D Misc/NEWS.d/next/Library/2019-07-09-19-38-26.bpo-37531.GX7s8S.rst D Misc/NEWS.d/next/Library/2019-07-10-23-07-11.bpo-21478.cCw9rF.rst D Misc/NEWS.d/next/Library/2019-07-13-10-59-43.bpo-37579.B1Tq9i.rst D Misc/NEWS.d/next/Library/2019-07-13-13-40-12.bpo-18378.NHcojp.rst D Misc/NEWS.d/next/Library/2019-07-13-16-02-48.bpo-37587.fd-1aF.rst D Misc/NEWS.d/next/Library/2019-07-17-06-54-43.bpo-37491.op0aMs.rst D Misc/NEWS.d/next/Library/2019-07-17-11-10-08.bpo-34443.OFnGqz.rst D Misc/NEWS.d/next/Library/2019-07-19-01-46-56.bpo-16970.GEASf5.rst D Misc/NEWS.d/next/Library/2019-07-19-16-06-48.bpo-29446.iXGuoi.rst D Misc/NEWS.d/next/Library/2019-07-19-20-13-48.bpo-37555.S5am28.rst D Misc/NEWS.d/next/Library/2019-07-19-22-44-41.bpo-36324.1VjywS.rst D Misc/NEWS.d/next/Library/2019-07-20-01-17-43.bpo-36161.Fzf-f9.rst D Misc/NEWS.d/next/Library/2019-07-21-20-59-31.bpo-37642.L61Bvy.rst D Misc/NEWS.d/next/Library/2019-07-24-14-38-53.bpo-37663.h4-9-1.rst D Misc/NEWS.d/next/Library/2019-07-24-18-27-44.bpo-37664.o-GYZC.rst D Misc/NEWS.d/next/Library/2019-07-25-10-28-40.bpo-37354.RT3_3H.rst D Misc/NEWS.d/next/Library/2019-07-26-00-12-29.bpo-37685.TqckMZ.rst D Misc/NEWS.d/next/Library/2019-07-26-22-30-01.bpo-37691.1Li3rx.rst D Misc/NEWS.d/next/Library/2019-07-27-10-14-45.bpo-29553.TVeIDe.rst D Misc/NEWS.d/next/Library/2019-07-27-18-00-43.bpo-37689.glEmZi.rst D Misc/NEWS.d/next/Library/2019-07-27-20-21-03.bpo-37695.QANdvg.rst D Misc/NEWS.d/next/Library/2019-07-28-17-44-21.bpo-37697.7UV5d0.rst D Misc/NEWS.d/next/Library/2019-07-28-22-25-25.bpo-37685._3bN9f.rst D Misc/NEWS.d/next/Library/2019-07-29-21-39-45.bpo-11953.4Hpwf9.rst D Misc/NEWS.d/next/Library/2019-07-30-01-27-29.bpo-37268.QDmA44.rst D Misc/NEWS.d/next/Library/2019-07-30-22-41-05.bpo-32178.X-IFLe.rst D Misc/NEWS.d/next/Library/2019-07-31-15-52-51.bpo-35943.-KswoB.rst D Misc/NEWS.d/next/Library/2019-07-31-16-49-01.bpo-37723.zq6tw8.rst D Misc/NEWS.d/next/Library/2019-08-01-17-11-16.bpo-37738.A3WWcT.rst D Misc/NEWS.d/next/Library/2019-08-02-14-01-25.bpo-37742.f4Xn9S.rst D Misc/NEWS.d/next/Library/2019-08-02-16-44-42.bpo-18049.OA4qBL.rst D Misc/NEWS.d/next/Library/2019-08-04-11-47-58.bpo-28292.vkihH5.rst D Misc/NEWS.d/next/Library/2019-08-04-17-22-33.bpo-37449.ycbL2z.rst D Misc/NEWS.d/next/Library/2019-08-06-21-30-58.bpo-34488.OqxVo8.rst D Misc/NEWS.d/next/Library/2019-08-07-14-49-22.bpo-37785.y7OlT8.rst D Misc/NEWS.d/next/Library/2019-08-07-19-34-07.bpo-18578.xfvdb_.rst D Misc/NEWS.d/next/Library/2019-08-07-23-48-09.bpo-37772.hLCvdn.rst D Misc/NEWS.d/next/Library/2019-08-10-12-33-27.bpo-37810.d4zbvB.rst D Misc/NEWS.d/next/Library/2019-08-10-18-50-04.bpo-14465.qZGC4g.rst D Misc/NEWS.d/next/Library/2019-08-11-10-34-19.bpo-37819.LVJls-.rst D Misc/NEWS.d/next/Library/2019-08-12-23-07-47.bpo-37804.Ene6L-.rst D Misc/NEWS.d/next/Library/2019-08-14-13-51-24.bpo-37798.AmXrik.rst D Misc/NEWS.d/next/Library/2019-08-14-15-34-23.bpo-21131.0MMQRi.rst D Misc/NEWS.d/next/Library/2019-08-14-20-46-39.bpo-37863.CkXqgX.rst D Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst D Misc/NEWS.d/next/Library/2019-08-17-22-33-54.bpo-37868.hp64fi.rst D Misc/NEWS.d/next/Library/2019-08-19-10-31-41.bpo-37885.4Nc9sp.rst D Misc/NEWS.d/next/Library/2019-08-20-05-17-32.bpo-32793.cgpXl6.rst D Misc/NEWS.d/next/Library/2019-08-21-13-43-04.bpo-37851.mIIfD_.rst D Misc/NEWS.d/next/Library/2019-08-21-16-38-56.bpo-9938.t3G7N9.rst D Misc/NEWS.d/next/Library/2019-08-22-01-49-05.bpo-32554.4xiXyM.rst D Misc/NEWS.d/next/Library/2019-08-22-16-13-27.bpo-37915.xyoZI5.rst D Misc/NEWS.d/next/Library/2019-08-23-00-55-19.bpo-26589.M1xyxG.rst D Misc/NEWS.d/next/Library/2019-08-24-16-54-49.bpo-37798.7mRQCk.rst D Misc/NEWS.d/next/Library/2019-08-25-14-56-42.bpo-36917.GBxdw2.rst D Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst D Misc/NEWS.d/next/Library/2019-08-26-10-45-51.bpo-37950.-K1IKT.rst D Misc/NEWS.d/next/Library/2019-08-27-03-53-26.bpo-36205.AfkGRl.rst D Misc/NEWS.d/next/Library/2019-08-27-10-03-48.bpo-37951.MfRQgL.rst D Misc/NEWS.d/next/Library/2019-08-27-10-30-44.bpo-37961.4nm0zZ.rst D Misc/NEWS.d/next/Library/2019-08-27-10-52-13.bpo-37960.CTY7Lw.rst D Misc/NEWS.d/next/Library/2019-08-27-21-19-28.bpo-37964.SxdnsF.rst D Misc/NEWS.d/next/Library/2019-08-28-14-04-18.bpo-37965.7xGE-C.rst D Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst D Misc/NEWS.d/next/Library/2019-08-29-01-19-13.bpo-10978.J6FQYY.rst D Misc/NEWS.d/next/Library/2019-08-29-16-41-36.bpo-37834.FThnsh.rst D Misc/NEWS.d/next/Library/2019-08-29-18-48-48.bpo-37587.N7TGTC.rst D Misc/NEWS.d/next/Library/2019-08-30-11-21-10.bpo-37140.cFAX-a.rst D Misc/NEWS.d/next/Library/2019-08-31-01-52-59.bpo-34410.7KbWZQ.rst D Misc/NEWS.d/next/Library/2019-08-31-13-36-09.bpo-37995.rS8HzT.rst D Misc/NEWS.d/next/Library/2019-09-02-13-37-27.bpo-38006.Y7vA0Q.rst D Misc/NEWS.d/next/Library/2019-09-02-14-30-39.bpo-38010.JOnz9Z.rst D Misc/NEWS.d/next/Library/2019-09-03-01-41-35.bpo-35923.lYpKbY.rst D Misc/NEWS.d/next/Library/2019-09-04-20-34-14.bpo-38026.0LLRX-.rst D Misc/NEWS.d/next/Library/2019-09-06-17-40-34.bpo-37953.db5FQq.rst D Misc/NEWS.d/next/Library/2019-09-07-12-32-50.bpo-38049.xKP4tf.rst D Misc/NEWS.d/next/Library/2019-09-08-11-36-50.bpo-38059.8SA6co.rst D Misc/NEWS.d/next/Library/2019-09-09-14-39-47.bpo-38066.l9mWv-.rst D Misc/NEWS.d/next/Library/2019-09-09-18-39-23.bpo-38037.B0UgFU.rst D Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst D Misc/NEWS.d/next/Library/2019-09-10-11-42-59.bpo-38086.w5TlG-.rst D Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst D Misc/NEWS.d/next/Library/2019-09-11-11-44-16.bpo-37488.S8CJUL.rst D Misc/NEWS.d/next/Library/2019-09-11-14-45-30.bpo-38093.yQ6k7y.rst D Misc/NEWS.d/next/Library/2019-09-11-14-49-20.bpo-38110.A19Y-q.rst D Misc/NEWS.d/next/Library/2019-09-11-16-54-57.bpo-38121.SrSDzB.rst D Misc/NEWS.d/next/Library/2019-09-11-20-27-41.bpo-37405.MG5xiY.rst D Misc/NEWS.d/next/Library/2019-09-11-21-38-41.bpo-34037.LIAS_3.rst D Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst D Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst D Misc/NEWS.d/next/Library/2019-09-12-13-18-55.bpo-38134.gXJTbP.rst D Misc/NEWS.d/next/Library/2019-09-12-14-52-38.bpo-36991.1OcSm8.rst D Misc/NEWS.d/next/Library/2019-09-12-14-54-45.bpo-9216.W7QMpC.rst D Misc/NEWS.d/next/Library/2019-09-12-18-41-35.bpo-38142.1I0Ch0.rst D Misc/NEWS.d/next/Library/2019-09-13-08-55-43.bpo-38148.Lnww6D.rst D Misc/NEWS.d/next/Library/2019-09-13-09-24-58.bpo-38115.BOO-Y1.rst D Misc/NEWS.d/next/Library/2019-09-13-12-18-51.bpo-38153.nHAbuJ.rst D Misc/NEWS.d/next/Library/2019-09-13-14-54-33.bpo-34706.HWVpOY.rst D Misc/NEWS.d/next/Library/2019-09-14-10-34-00.bpo-33936.8wCI_n.rst D Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst D Misc/NEWS.d/next/Library/2019-09-15-21-31-18.bpo-37828.gLLDX7.rst D Misc/NEWS.d/next/Library/2019-09-16-09-54-42.bpo-38136.MdI-Zb.rst D Misc/NEWS.d/next/Library/2019-09-16-19-12-57.bpo-38185.zYWppY.rst D Misc/NEWS.d/next/Library/2019-09-16-21-47-48.bpo-38155.d92lRc.rst D Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst D Misc/NEWS.d/next/Library/2019-09-19-19-58-33.bpo-34002.KBnaVX.rst D Misc/NEWS.d/next/Library/2019-09-20-14-27-17.bpo-38237.xRUZbx.rst D Misc/NEWS.d/next/Library/2019-09-22-13-05-36.bpo-38248.Yo3N_1.rst D Misc/NEWS.d/next/Library/2019-09-24-10-55-01.bpo-38112.2EinX9.rst D Misc/NEWS.d/next/Library/2019-09-25-05-16-19.bpo-38265.X6-gsT.rst D Misc/NEWS.d/next/Library/2019-09-25-21-37-02.bpo-38108.Jr9HU6.rst D Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst D Misc/NEWS.d/next/Library/2019-09-27-15-24-45.bpo-38216.-7yvZR.rst D Misc/NEWS.d/next/Library/2019-09-27-16-31-28.bpo-38161.zehai1.rst D Misc/NEWS.d/next/Library/2019-09-28-20-16-40.bpo-38163.x51-vK.rst D Misc/NEWS.d/next/Library/2019-09-29-13-50-24.bpo-38019.6MoOE3.rst D Misc/NEWS.d/next/Library/2019-09-29-22-47-37.bpo-13153.0mO9qR.rst D Misc/NEWS.d/next/Library/2019-09-30-00-15-27.bpo-38242.uPIyAc.rst D Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst D Misc/NEWS.d/next/Library/2019-10-01-21-06-18.bpo-38341.uqwgU_.rst D Misc/NEWS.d/next/Library/2019-10-04-18-39-59.bpo-38371.S6Klvm.rst D Misc/NEWS.d/next/Library/2019-10-05-02-07-52.bpo-38332.hwrPN7.rst D Misc/NEWS.d/next/Library/2019-10-08-11-18-40.bpo-38405.0-7e7s.rst D Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst D Misc/NEWS.d/next/Library/2019-10-10-00-25-28.bpo-38109.9w-IGF.rst D Misc/NEWS.d/next/Library/2019-10-10-16-53-00.bpo-38431.d5wzNp.rst D Misc/NEWS.d/next/Library/2019-10-11-18-49-00.bpo-38449.9TWMlz.rst D Misc/NEWS.d/next/Library/2019-10-12-00-13-47.bpo-38417.W7x_aS.rst D Misc/NEWS.d/next/Library/2019-10-13-11-00-03.bpo-38378.yYNpSm.rst D Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst D Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst D Misc/NEWS.d/next/Library/2019-10-16-19-56-51.bpo-38493.86ExWB.rst D Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst D Misc/NEWS.d/next/Library/2019-10-19-21-41-20.bpo-36321.CFlxfy.rst D Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst D Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst D Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst D Misc/NEWS.d/next/Library/2019-10-24-17-26-39.bpo-38586.cyq5nr.rst D Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst D Misc/NEWS.d/next/Library/2019-10-27-00-08-49.bpo-38334.pfLLmc.rst D Misc/NEWS.d/next/Library/2019-10-27-22-29-45.bpo-38602.7jvYFA.rst D Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst D Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst D Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst D Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst D Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst D Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst D Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst D Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst D Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst D Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst D Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst D Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst D Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst D Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst D Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst D Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst D Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst D Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst D Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst D Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst D Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.rst D Misc/NEWS.d/next/Security/2019-09-23-21-02-46.bpo-38174.MeWuJd.rst D Misc/NEWS.d/next/Security/2019-09-25-13-21-09.bpo-38243.1pfz24.rst D Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst D Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst D Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst D Misc/NEWS.d/next/Tests/2018-09-07-01-18-27.bpo-34596.r2-EGd.rst D Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst D Misc/NEWS.d/next/Tests/2019-04-15-19-05-35.bpo-30202.Wt7INj.rst D Misc/NEWS.d/next/Tests/2019-05-28-15-41-34.bpo-36919.-vGt_m.rst D Misc/NEWS.d/next/Tests/2019-06-03-20-47-10.bpo-34001.KvYx9z.rst D Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst D Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst D Misc/NEWS.d/next/Tests/2019-06-12-14-30-29.bpo-37252.4o-uLs.rst D Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst D Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst D Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst D Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst D Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst D Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst D Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst D Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst D Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst D Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst D Misc/NEWS.d/next/Tests/2019-06-29-16-02-21.bpo-19696.05ijhN.rst D Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst D Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst D Misc/NEWS.d/next/Tests/2019-07-01-19-56-17.bpo-37421.bOe350.rst D Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst D Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst D Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst D Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst D Misc/NEWS.d/next/Tests/2019-07-05-14-47-55.bpo-37421.n8o2to.rst D Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst D Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst D Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst D Misc/NEWS.d/next/Tests/2019-07-18-14-52-58.bpo-36833.Zoe9ek.rst D Misc/NEWS.d/next/Tests/2019-08-16-16-15-14.bpo-37876.m3k1w3.rst D Misc/NEWS.d/next/Tests/2019-08-20-19-24-19.bpo-37531.wRoXfU.rst D Misc/NEWS.d/next/Tests/2019-08-25-19-51-46.bpo-37805.Kl1sti.rst D Misc/NEWS.d/next/Tests/2019-09-03-19-33-10.bpo-38018.zTrMu7.rst D Misc/NEWS.d/next/Tests/2019-09-11-17-22-32.bpo-38117.X7LgGY.rst D Misc/NEWS.d/next/Tests/2019-09-24-12-24-05.bpo-38212.IWbhWz.rst D Misc/NEWS.d/next/Tests/2019-09-24-12-30-55.bpo-37123.IoutBn.rst D Misc/NEWS.d/next/Tests/2019-09-25-12-18-31.bpo-38270._x-9uH.rst D Misc/NEWS.d/next/Tests/2019-09-25-13-11-29.bpo-38271.iHXNIg.rst D Misc/NEWS.d/next/Tests/2019-09-25-14-40-57.bpo-38275.-kdveI.rst D Misc/NEWS.d/next/Tests/2019-09-26-15-48-36.bpo-38239.MfoVzY.rst D Misc/NEWS.d/next/Tests/2019-10-08-16-42-05.bpo-37531.7v-_Ca.rst D Misc/NEWS.d/next/Tests/2019-10-14-22-46-35.bpo-38470.NHtzpy.rst D Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst D Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst D Misc/NEWS.d/next/Tests/2019-10-28-15-56-02.bpo-38614.aDdDYE.rst D Misc/NEWS.d/next/Tests/2019-10-30-15-12-32.bpo-38614.M6UnLB.rst D Misc/NEWS.d/next/Tools-Demos/2019-05-27-15-26-12.bpo-37064.k_SPW2.rst D Misc/NEWS.d/next/Tools-Demos/2019-05-27-16-13-08.bpo-37034.zbTgy8.rst D Misc/NEWS.d/next/Tools-Demos/2019-07-24-16-20-54.bpo-37675.951Cvf.rst D Misc/NEWS.d/next/Tools-Demos/2019-07-29-13-59-19.bpo-37704.xxGUz_.rst D Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst D Misc/NEWS.d/next/Tools-Demos/2019-09-12-16-15-55.bpo-37803.chEizy.rst D Misc/NEWS.d/next/Tools-Demos/2019-10-02-09-48-42.bpo-38347.2Tq5D1.rst D Misc/NEWS.d/next/Tools-Demos/2019-10-08-15-07-52.bpo-38118.pIZD6H.rst D Misc/NEWS.d/next/Windows/2019-04-10-21-13-26.bpo-36590.ZTaKcu.rst D Misc/NEWS.d/next/Windows/2019-05-05-05-23-34.bpo-28269.-MOHI7.rst D Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst D Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst D Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst D Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst D Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst D Misc/NEWS.d/next/Windows/2019-06-25-04-15-22.bpo-37380.tPxjuz.rst D Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst D Misc/NEWS.d/next/Windows/2019-06-28-18-10-29.bpo-37445.LsdYO6.rst D Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst D Misc/NEWS.d/next/Windows/2019-07-24-14-36-28.bpo-37672.uKEVHN.rst D Misc/NEWS.d/next/Windows/2019-07-29-16-49-31.bpo-37702.Lj2f5e.rst D Misc/NEWS.d/next/Windows/2019-08-06-09-35-12.bpo-37734.EoJ9Nh.rst D Misc/NEWS.d/next/Windows/2019-08-06-13-54-12.bpo-37778.AY1XhH.rst D Misc/NEWS.d/next/Windows/2019-08-06-18-09-18.bpo-25172.Akreij.rst D Misc/NEWS.d/next/Windows/2019-08-08-18-05-27.bpo-36266.x4eZU3.rst D Misc/NEWS.d/next/Windows/2019-08-12-12-00-24.bpo-37834.VB2QVj.rst D Misc/NEWS.d/next/Windows/2019-08-14-13-40-15.bpo-9949.zW45Ks.rst D Misc/NEWS.d/next/Windows/2019-08-21-12-58-18.bpo-1311.BoW1wU.rst D Misc/NEWS.d/next/Windows/2019-08-22-09-04-44.bpo-37549.TpKI3M.rst D Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst D Misc/NEWS.d/next/Windows/2019-09-03-11-47-37.bpo-38020.xFZ2j0.rst D Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst D Misc/NEWS.d/next/Windows/2019-09-09-12-22-23.bpo-37283.8NvOkU.rst D Misc/NEWS.d/next/Windows/2019-09-10-14-17-25.bpo-38088.FOvWSM.rst D Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst D Misc/NEWS.d/next/Windows/2019-09-11-10-22-01.bpo-38081.8JhzjD.rst D Misc/NEWS.d/next/Windows/2019-09-11-12-34-31.bpo-36634.xLaGgb.rst D Misc/NEWS.d/next/Windows/2019-09-11-14-42-04.bpo-36634.8Un8ih.rst D Misc/NEWS.d/next/Windows/2019-09-11-14-51-56.bpo-32592.jvQMD9.rst D Misc/NEWS.d/next/Windows/2019-09-11-15-24-04.bpo-38114.cc0E5E.rst D Misc/NEWS.d/next/Windows/2019-09-12-12-05-55.bpo-38133.yFeRGS.rst D Misc/NEWS.d/next/Windows/2019-09-13-14-11-42.bpo-38092.x31ehI.rst D Misc/NEWS.d/next/Windows/2019-09-16-14-07-11.bpo-38117.hJVf0C.rst D Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst D Misc/NEWS.d/next/Windows/2019-10-03-08-04-14.bpo-38359.wzwsl_.rst D Misc/NEWS.d/next/Windows/2019-10-05-05-50-58.bpo-38344.scr2LO.rst D Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst D Misc/NEWS.d/next/Windows/2019-10-28-05-01-29.bpo-38519.dCkY66.rst D Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst D Misc/NEWS.d/next/Windows/2019-10-28-10-48-16.bpo-38589.V69Q1a.rst D Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst D Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst D Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst D Misc/NEWS.d/next/macOS/2019-07-13-15-58-18.bpo-18049.MklhQQ.rst D Misc/NEWS.d/next/macOS/2019-09-10-14-24-35.bpo-38089.eedgyD.rst D Misc/NEWS.d/next/macOS/2019-09-15-21-29-13.bpo-38117.ZLsoAZ.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index ad5599462a8bd..7dd3dd1a41894 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 9 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 0 +#define PY_RELEASE_SERIAL 1 =20 /* Version as a string */ -#define PY_VERSION "3.9.0a0" +#define PY_VERSION "3.9.0a1" /*--end constants--*/ =20 /* Version as a single 4-byte hex number, e.g. 0x010502B2 =3D=3D 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index d3559e445ab01..c3fe0798943f4 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Jun 4 19:40:37 2019 +# Autogenerated by Sphinx on Tue Nov 19 11:42:25 2019 topics =3D {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -744,10 +744,11 @@ 'returned.\n' '\n' 'The "__dir__" function should accept no arguments, and= ' - 'return a list\n' - 'of strings that represents the names accessible on ' - 'module. If present,\n' - 'this function overrides the standard "dir()" search on= a ' + 'return a\n' + 'sequence of strings that represents the names accessib= le ' + 'on module. If\n' + 'present, this function overrides the standard "dir()" ' + 'search on a\n' 'module.\n' '\n' 'For a more fine grained customization of the module ' @@ -808,21 +809,34 @@ 'whose name is\n' 'the key of the property in the owner class=E2=80=99 "_= _dict__".\n' '\n' - 'object.__get__(self, instance, owner)\n' + 'object.__get__(self, instance, owner=3DNone)\n' '\n' ' Called to get the attribute of the owner class (cla= ss ' 'attribute\n' ' access) or of an instance of that class (instance ' 'attribute\n' - ' access). *owner* is always the owner class, while ' - '*instance* is the\n' - ' instance that the attribute was accessed through, o= r ' - '"None" when\n' - ' the attribute is accessed through the *owner*. Thi= s ' - 'method should\n' - ' return the (computed) attribute value or raise an ' - '"AttributeError"\n' - ' exception.\n' + ' access). The optional *owner* argument is the owner= ' + 'class, while\n' + ' *instance* is the instance that the attribute was ' + 'accessed through,\n' + ' or "None" when the attribute is accessed through th= e ' + '*owner*.\n' + '\n' + ' This method should return the computed attribute ' + 'value or raise an\n' + ' "AttributeError" exception.\n' + '\n' + ' **PEP 252** specifies that "__get__()" is callable ' + 'with one or two\n' + ' arguments. Python=E2=80=99s own built-in descripto= rs support ' + 'this\n' + ' specification; however, it is likely that some ' + 'third-party tools\n' + ' have descriptors that require both arguments. ' + 'Python=E2=80=99s own\n' + ' "__getattribute__()" implementation always passes i= n ' + 'both arguments\n' + ' whether they are required or not.\n' '\n' 'object.__set__(self, instance, value)\n' '\n' @@ -830,6 +844,12 @@ 'of the owner\n' ' class to a new value, *value*.\n' '\n' + ' Note, adding "__set__()" or "__delete__()" changes ' + 'the kind of\n' + ' descriptor to a =E2=80=9Cdata descriptor=E2=80=9D. = See Invoking ' + 'Descriptors for\n' + ' more details.\n' + '\n' 'object.__delete__(self, instance)\n' '\n' ' Called to delete the attribute on an instance ' @@ -938,12 +958,13 @@ 'define both\n' '"__get__()" and "__set__()", while non-data descriptor= s ' 'have just the\n' - '"__get__()" method. Data descriptors with "__set__()"= ' - 'and "__get__()"\n' - 'defined always override a redefinition in an instance ' - 'dictionary. In\n' - 'contrast, non-data descriptors can be overridden by ' - 'instances.\n' + '"__get__()" method. Data descriptors with "__get__()"= ' + 'and "__set__()"\n' + '(and/or "__delete__()") defined always override a ' + 'redefinition in an\n' + 'instance dictionary. In contrast, non-data descriptor= s ' + 'can be\n' + 'overridden by instances.\n' '\n' 'Python methods (including "staticmethod()" and ' '"classmethod()") are\n' @@ -1070,7 +1091,13 @@ 'attributes created by\n' ' slots (the other bases must have empty slot layouts)= - ' 'violations\n' - ' raise "TypeError".\n', + ' raise "TypeError".\n' + '\n' + '* If an iterator is used for *__slots__* then a ' + 'descriptor is\n' + ' created for each of the iterator=E2=80=99s values. H= owever, ' + 'the *__slots__*\n' + ' attribute will be an empty iterator.\n', 'attribute-references': 'Attribute references\n' '********************\n' '\n' @@ -1829,6 +1856,12 @@ 'all false.\n' ' This behavior is compliant with IEEE 754.\n' '\n' + '* "None" and "NotImplemented" are singletons. **PEP 8** ' + 'advises\n' + ' that comparisons for singletons should always be done wit= h ' + '"is" or\n' + ' "is not", never the equality operators.\n' + '\n' '* Binary sequences (instances of "bytes" or "bytearray") ca= n ' 'be\n' ' compared within and across their types. They compare\n' @@ -1854,38 +1887,13 @@ ' these types raises "TypeError".\n' '\n' ' Sequences compare lexicographically using comparison of\n' - ' corresponding elements, whereby reflexivity of the elemen= ts ' - 'is\n' - ' enforced.\n' - '\n' - ' In enforcing reflexivity of elements, the comparison of ' - 'collections\n' - ' assumes that for a collection element "x", "x =3D=3D x" i= s ' - 'always true.\n' - ' Based on that assumption, element identity is compared ' - 'first, and\n' - ' element comparison is performed only for distinct ' - 'elements. This\n' - ' approach yields the same result as a strict element ' - 'comparison\n' - ' would, if the compared elements are reflexive. For ' - 'non-reflexive\n' - ' elements, the result is different than for strict element= \n' - ' comparison, and may be surprising: The non-reflexive ' - 'not-a-number\n' - ' values for example result in the following comparison ' - 'behavior when\n' - ' used in a list:\n' - '\n' - " >>> nan =3D float('NaN')\n" - ' >>> nan is nan\n' - ' True\n' - ' >>> nan =3D=3D nan\n' - ' False <-- the defined non-reflexive ' - 'behavior of NaN\n' - ' >>> [nan] =3D=3D [nan]\n' - ' True <-- list enforces reflexivity an= d ' - 'tests identity first\n' + ' corresponding elements. The built-in containers typicall= y ' + 'assume\n' + ' identical objects are equal to themselves. That lets the= m ' + 'bypass\n' + ' equality tests for identical objects to improve performan= ce ' + 'and to\n' + ' maintain their internal invariants.\n' '\n' ' Lexicographical comparison between built-in collections ' 'works as\n' @@ -3126,13 +3134,15 @@ 'returning\n' ' it.\n' '\n' - ' If "__new__()" returns an instance of *cls*, then the ' - 'new\n' - ' instance=E2=80=99s "__init__()" method will be invoked= like\n' - ' "__init__(self[, ...])", where *self* is the new ' - 'instance and the\n' - ' remaining arguments are the same as were passed to ' - '"__new__()".\n' + ' If "__new__()" is invoked during object construction a= nd ' + 'it returns\n' + ' an instance or subclass of *cls*, then the new ' + 'instance=E2=80=99s\n' + ' "__init__()" method will be invoked like ' + '"__init__(self[, ...])",\n' + ' where *self* is the new instance and the remaining ' + 'arguments are\n' + ' the same as were passed to the object constructor.\n' '\n' ' If "__new__()" does not return an instance of *cls*, ' 'then the new\n' @@ -3500,10 +3510,10 @@ ' hashable by an "isinstance(obj, ' 'collections.abc.Hashable)" call.\n' '\n' - ' Note: By default, the "__hash__()" values of str, byte= s ' - 'and\n' - ' datetime objects are =E2=80=9Csalted=E2=80=9D with a= n unpredictable ' - 'random value.\n' + ' Note: By default, the "__hash__()" values of str and ' + 'bytes\n' + ' objects are =E2=80=9Csalted=E2=80=9D with an unpredi= ctable random ' + 'value.\n' ' Although they remain constant within an individual ' 'Python\n' ' process, they are not predictable between repeated ' @@ -3758,6 +3768,8 @@ '\n' " import pdb; pdb.Pdb(skip=3D['django.*']).set_trace()\n" '\n' + ' Raises an auditing event "pdb.Pdb" with no arguments.\n' + '\n' ' New in version 3.1: The *skip* argument.\n' '\n' ' New in version 3.2: The *nosigint* argument. Previously, a= ' @@ -4289,7 +4301,14 @@ 'section The standard type hierarchy. (To summarize, the key type\= n' 'should be *hashable*, which excludes all mutable objects.) Clashe= s\n' 'between duplicate keys are not detected; the last datum (textually= \n' - 'rightmost in the display) stored for a given key value prevails.\n= ', + 'rightmost in the display) stored for a given key value prevails.\n' + '\n' + 'Changed in version 3.8: Prior to Python 3.8, in dict ' + 'comprehensions,\n' + 'the evaluation order of key and value was not well-defined. In\n' + 'CPython, the value was evaluated before the key. Starting with ' + '3.8,\n' + 'the key is evaluated before the value, as proposed by **PEP 572**.= \n', 'dynamic-features': 'Interaction with dynamic features\n' '*********************************\n' '\n' @@ -4430,9 +4449,13 @@ '(a\n' 'command specified on the interpreter command line with the ' '"-c"\n' - 'option) is a code block. The string argument passed to the ' - 'built-in\n' - 'functions "eval()" and "exec()" is a code block.\n' + 'option) is a code block. A module run as a top level script (= as ' + 'module\n' + '"__main__") from the command line using a "-m" argument is al= so ' + 'a code\n' + 'block. The string argument passed to the built-in functions ' + '"eval()"\n' + 'and "exec()" is a code block.\n' '\n' 'A code block is executed in an *execution frame*. A frame ' 'contains\n' @@ -5090,7 +5113,7 @@ 'Meaning = ' '|\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D|\n' ' | "\'<\'" | Forces the field to be left-aligned ' 'within the available |\n' ' | | space (this is the default for most ' @@ -5139,7 +5162,7 @@ 'Meaning = ' '|\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D|\n' ' | "\'+\'" | indicates that a sign should be used f= or ' 'both positive as |\n' ' | | well as negative ' @@ -5243,7 +5266,7 @@ 'Meaning = ' '|\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D|\n' ' | "\'s\'" | String format. This is the default typ= e ' 'for strings and |\n' ' | | may be ' @@ -5263,7 +5286,7 @@ 'Meaning = ' '|\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D|\n' ' | "\'b\'" | Binary format. Outputs the number in ' 'base 2. |\n' ' ' @@ -5325,7 +5348,7 @@ 'Meaning = ' '|\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D|\n' ' | "\'e\'" | Exponent notation. Prints the number i= n ' 'scientific |\n' ' | | notation using the letter =E2=80=98e=E2= =80=99 to indicate ' @@ -5364,30 +5387,34 @@ 'the result |\n' ' | | formatted with presentation type "\'e\'"= ' 'and precision "p-1" |\n' - ' | | would have exponent "exp". Then if "-4 = <=3D ' - 'exp < p", the |\n' - ' | | number is formatted with presentation ty= pe ' - '"\'f\'" and |\n' - ' | | precision "p-1-exp". Otherwise, the ' - 'number is formatted |\n' - ' | | with presentation type "\'e\'" and ' - 'precision "p-1". In both |\n' - ' | | cases insignificant trailing zeros are ' - 'removed from the |\n' + ' | | would have exponent "exp". Then, if "m = <=3D ' + 'exp < p", where |\n' + ' | | "m" is -4 for floats and -6 for ' + '"Decimals", the number is |\n' + ' | | formatted with presentation type "\'f\'"= ' + 'and precision |\n' + ' | | "p-1-exp". Otherwise, the number is ' + 'formatted with |\n' + ' | | presentation type "\'e\'" and precision ' + '"p-1". In both cases |\n' + ' | | insignificant trailing zeros are removed= ' + 'from the |\n' ' | | significand, and the decimal point is al= so ' 'removed if |\n' ' | | there are no remaining digits following ' - 'it. Positive and |\n' - ' | | negative infinity, positive and negative= ' - 'zero, and nans, |\n' - ' | | are formatted as "inf", "-inf", "0", "-0= " ' - 'and "nan" |\n' - ' | | respectively, regardless of the ' - 'precision. A precision of |\n' - ' | | "0" is treated as equivalent to a ' - 'precision of "1". The |\n' - ' | | default precision is ' - '"6". |\n' + 'it, unless the |\n' + ' | | "\'#\'" option is used. Positive and ' + 'negative infinity, |\n' + ' | | positive and negative zero, and nans, ar= e ' + 'formatted as |\n' + ' | | "inf", "-inf", "0", "-0" and "nan" ' + 'respectively, |\n' + ' | | regardless of the precision. A precisio= n ' + 'of "0" is |\n' + ' | | treated as equivalent to a precision of ' + '"1". The default |\n' + ' | | precision is ' + '"6". |\n' ' ' '+-----------+--------------------------------------------= ----------------+\n' ' | "\'G\'" | General format. Same as "\'g\'" except= ' @@ -6212,6 +6239,10 @@ 'that\n' 'determine dynamically the modules to be loaded.\n' '\n' + 'Raises an auditing event "import" with arguments "module", ' + '"filename",\n' + '"sys.path", "sys.meta_path", "sys.path_hooks".\n' + '\n' '\n' 'Future statements\n' '=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n' @@ -7036,7 +7067,10 @@ '+-------------------------------------------------+---= ------------------------------------+\n' '| Operator | ' 'Description |\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' + '| ":=3D" | ' + 'Assignment expression |\n' + '+-------------------------------------------------+---= ------------------------------------+\n' '| "lambda" | ' 'Lambda expression |\n' '+-------------------------------------------------+---= ------------------------------------+\n' @@ -7093,10 +7127,10 @@ '| "x(arguments...)", "x.attribute" | ' 'attribute reference |\n' '+-------------------------------------------------+---= ------------------------------------+\n' - '| "(expressions...)", "[expressions...]", "{key: | ' - 'Binding or tuple display, list |\n' - '| value...}", "{expressions...}" | ' - 'display, dictionary display, set |\n' + '| "(expressions...)", "[expressions...]", "{key: | ' + 'Binding or parenthesized expression, |\n' + '| value...}", "{expressions...}" | li= st ' + 'display, dictionary display, set |\n' '| | ' 'display |\n' '+-------------------------------------------------+---= ------------------------------------+\n' @@ -7432,9 +7466,9 @@ 'to allow\n' 'efficient iteration through the container; for mappings,= ' '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should= ' - 'iterate\n' - 'through the values.\n' + 'should iterate through the object=E2=80=99s keys; for se= quences, ' + 'it should\n' + 'iterate through the values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -7464,7 +7498,11 @@ ' estimated length for the object (which may be greater= ' 'or less than\n' ' the actual length). The length must be an integer ">= =3D" ' - '0. This\n' + '0. The\n' + ' return value may also be "NotImplemented", which is ' + 'treated the\n' + ' same as if the "__length_hint__" method didn=E2=80=99= t exist at ' + 'all. This\n' ' method is purely an optimization and is never require= d ' 'for\n' ' correctness.\n' @@ -7582,12 +7620,12 @@ '\n' 'The membership test operators ("in" and "not in") are ' 'normally\n' - 'implemented as an iteration through a sequence. However= , ' + 'implemented as an iteration through a container. However= , ' 'container\n' 'objects can supply the following special method with a ' 'more efficient\n' 'implementation, which also does not require the object b= e ' - 'a sequence.\n' + 'iterable.\n' '\n' 'object.__contains__(self, item)\n' '\n' @@ -7832,13 +7870,15 @@ 'returning\n' ' it.\n' '\n' - ' If "__new__()" returns an instance of *cls*, then the ' - 'new\n' - ' instance=E2=80=99s "__init__()" method will be invoked = like\n' - ' "__init__(self[, ...])", where *self* is the new instan= ce ' - 'and the\n' - ' remaining arguments are the same as were passed to ' - '"__new__()".\n' + ' If "__new__()" is invoked during object construction an= d ' + 'it returns\n' + ' an instance or subclass of *cls*, then the new ' + 'instance=E2=80=99s\n' + ' "__init__()" method will be invoked like "__init__(self= [, ' + '...])",\n' + ' where *self* is the new instance and the remaining ' + 'arguments are\n' + ' the same as were passed to the object constructor.\n' '\n' ' If "__new__()" does not return an instance of *cls*, th= en ' 'the new\n' @@ -8203,10 +8243,10 @@ ' hashable by an "isinstance(obj, ' 'collections.abc.Hashable)" call.\n' '\n' - ' Note: By default, the "__hash__()" values of str, bytes= ' - 'and\n' - ' datetime objects are =E2=80=9Csalted=E2=80=9D with an= unpredictable ' - 'random value.\n' + ' Note: By default, the "__hash__()" values of str and ' + 'bytes\n' + ' objects are =E2=80=9Csalted=E2=80=9D with an unpredic= table random ' + 'value.\n' ' Although they remain constant within an individual ' 'Python\n' ' process, they are not predictable between repeated ' @@ -8367,10 +8407,11 @@ 'returned.\n' '\n' 'The "__dir__" function should accept no arguments, and ' - 'return a list\n' - 'of strings that represents the names accessible on module.= ' - 'If present,\n' - 'this function overrides the standard "dir()" search on a ' + 'return a\n' + 'sequence of strings that represents the names accessible o= n ' + 'module. If\n' + 'present, this function overrides the standard "dir()" sear= ch ' + 'on a\n' 'module.\n' '\n' 'For a more fine grained customization of the module behavi= or ' @@ -8431,21 +8472,34 @@ 'whose name is\n' 'the key of the property in the owner class=E2=80=99 "__dic= t__".\n' '\n' - 'object.__get__(self, instance, owner)\n' + 'object.__get__(self, instance, owner=3DNone)\n' '\n' ' Called to get the attribute of the owner class (class ' 'attribute\n' ' access) or of an instance of that class (instance ' 'attribute\n' - ' access). *owner* is always the owner class, while ' - '*instance* is the\n' - ' instance that the attribute was accessed through, or ' - '"None" when\n' - ' the attribute is accessed through the *owner*. This ' - 'method should\n' - ' return the (computed) attribute value or raise an ' - '"AttributeError"\n' - ' exception.\n' + ' access). The optional *owner* argument is the owner ' + 'class, while\n' + ' *instance* is the instance that the attribute was ' + 'accessed through,\n' + ' or "None" when the attribute is accessed through the ' + '*owner*.\n' + '\n' + ' This method should return the computed attribute value = or ' + 'raise an\n' + ' "AttributeError" exception.\n' + '\n' + ' **PEP 252** specifies that "__get__()" is callable with= ' + 'one or two\n' + ' arguments. Python=E2=80=99s own built-in descriptors s= upport ' + 'this\n' + ' specification; however, it is likely that some ' + 'third-party tools\n' + ' have descriptors that require both arguments. Python= =E2=80=99s ' + 'own\n' + ' "__getattribute__()" implementation always passes in bo= th ' + 'arguments\n' + ' whether they are required or not.\n' '\n' 'object.__set__(self, instance, value)\n' '\n' @@ -8453,6 +8507,12 @@ 'the owner\n' ' class to a new value, *value*.\n' '\n' + ' Note, adding "__set__()" or "__delete__()" changes the ' + 'kind of\n' + ' descriptor to a =E2=80=9Cdata descriptor=E2=80=9D. See= Invoking ' + 'Descriptors for\n' + ' more details.\n' + '\n' 'object.__delete__(self, instance)\n' '\n' ' Called to delete the attribute on an instance *instance= * ' @@ -8559,12 +8619,13 @@ 'both\n' '"__get__()" and "__set__()", while non-data descriptors ha= ve ' 'just the\n' - '"__get__()" method. Data descriptors with "__set__()" and= ' - '"__get__()"\n' - 'defined always override a redefinition in an instance ' - 'dictionary. In\n' - 'contrast, non-data descriptors can be overridden by ' - 'instances.\n' + '"__get__()" method. Data descriptors with "__get__()" and= ' + '"__set__()"\n' + '(and/or "__delete__()") defined always override a ' + 'redefinition in an\n' + 'instance dictionary. In contrast, non-data descriptors ca= n ' + 'be\n' + 'overridden by instances.\n' '\n' 'Python methods (including "staticmethod()" and ' '"classmethod()") are\n' @@ -8691,6 +8752,12 @@ 'violations\n' ' raise "TypeError".\n' '\n' + '* If an iterator is used for *__slots__* then a descriptor= ' + 'is\n' + ' created for each of the iterator=E2=80=99s values. Howev= er, the ' + '*__slots__*\n' + ' attribute will be an empty iterator.\n' + '\n' '\n' 'Customizing class creation\n' '=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D\n' @@ -9136,9 +9203,9 @@ 'allow\n' 'efficient iteration through the container; for mappings, ' '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should ' - 'iterate\n' - 'through the values.\n' + 'should iterate through the object=E2=80=99s keys; for sequ= ences, it ' + 'should\n' + 'iterate through the values.\n' '\n' 'object.__len__(self)\n' '\n' @@ -9167,7 +9234,11 @@ ' estimated length for the object (which may be greater o= r ' 'less than\n' ' the actual length). The length must be an integer ">=3D= " 0. ' - 'This\n' + 'The\n' + ' return value may also be "NotImplemented", which is ' + 'treated the\n' + ' same as if the "__length_hint__" method didn=E2=80=99t = exist at ' + 'all. This\n' ' method is purely an optimization and is never required ' 'for\n' ' correctness.\n' @@ -9285,12 +9356,12 @@ '\n' 'The membership test operators ("in" and "not in") are ' 'normally\n' - 'implemented as an iteration through a sequence. However, ' + 'implemented as an iteration through a container. However, ' 'container\n' 'objects can supply the following special method with a mor= e ' 'efficient\n' - 'implementation, which also does not require the object be = a ' - 'sequence.\n' + 'implementation, which also does not require the object be ' + 'iterable.\n' '\n' 'object.__contains__(self, item)\n' '\n' @@ -9756,9 +9827,21 @@ 'For a list\n' ' of possible encodings, see section Standard Encodings= .\n' '\n' + ' By default, the *errors* argument is not checked for ' + 'best\n' + ' performances, but only used at the first encoding ' + 'error. Enable the\n' + ' development mode ("-X" "dev" option), or use a debug ' + 'build, to\n' + ' check *errors*.\n' + '\n' ' Changed in version 3.1: Support for keyword arguments= ' 'added.\n' '\n' + ' Changed in version 3.9: The *errors* is now checked i= n ' + 'development\n' + ' mode and in debug mode.\n' + '\n' 'str.endswith(suffix[, start[, end]])\n' '\n' ' Return "True" if the string ends with the specified ' @@ -9894,20 +9977,20 @@ '\n' 'str.isalnum()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'alphanumeric and\n' - ' there is at least one character, false otherwise. A ' - 'character "c"\n' - ' is alphanumeric if one of the following returns ' + ' there is at least one character, "False" otherwise. = A ' + 'character\n' + ' "c" is alphanumeric if one of the following returns ' '"True":\n' ' "c.isalpha()", "c.isdecimal()", "c.isdigit()", or ' '"c.isnumeric()".\n' '\n' 'str.isalpha()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'alphabetic and\n' - ' there is at least one character, false otherwise. ' + ' there is at least one character, "False" otherwise. ' 'Alphabetic\n' ' characters are those characters defined in the Unicod= e ' 'character\n' @@ -9921,45 +10004,46 @@ '\n' 'str.isascii()\n' '\n' - ' Return true if the string is empty or all characters = in ' - 'the string\n' - ' are ASCII, false otherwise. ASCII characters have cod= e ' - 'points in\n' - ' the range U+0000-U+007F.\n' + ' Return "True" if the string is empty or all character= s ' + 'in the\n' + ' string are ASCII, "False" otherwise. ASCII characters= ' + 'have code\n' + ' points in the range U+0000-U+007F.\n' '\n' ' New in version 3.7.\n' '\n' 'str.isdecimal()\n' '\n' - ' Return true if all characters in the string are decim= al ' - 'characters\n' - ' and there is at least one character, false otherwise.= ' - 'Decimal\n' - ' characters are those that can be used to form numbers= ' - 'in base 10,\n' - ' e.g. U+0660, ARABIC-INDIC DIGIT ZERO. Formally a ' - 'decimal character\n' - ' is a character in the Unicode General Category =E2=80= =9CNd=E2=80=9D.\n' + ' Return "True" if all characters in the string are ' + 'decimal\n' + ' characters and there is at least one character, "Fals= e" ' + 'otherwise.\n' + ' Decimal characters are those that can be used to form= ' + 'numbers in\n' + ' base 10, e.g. U+0660, ARABIC-INDIC DIGIT ZERO. ' + 'Formally a decimal\n' + ' character is a character in the Unicode General ' + 'Category =E2=80=9CNd=E2=80=9D.\n' '\n' 'str.isdigit()\n' '\n' - ' Return true if all characters in the string are digit= s ' - 'and there is\n' - ' at least one character, false otherwise. Digits ' - 'include decimal\n' - ' characters and digits that need special handling, suc= h ' - 'as the\n' - ' compatibility superscript digits. This covers digits ' - 'which cannot\n' - ' be used to form numbers in base 10, like the Kharosth= i ' - 'numbers.\n' - ' Formally, a digit is a character that has the propert= y ' - 'value\n' - ' Numeric_Type=3DDigit or Numeric_Type=3DDecimal.\n' + ' Return "True" if all characters in the string are ' + 'digits and there\n' + ' is at least one character, "False" otherwise. Digits= ' + 'include\n' + ' decimal characters and digits that need special ' + 'handling, such as\n' + ' the compatibility superscript digits. This covers ' + 'digits which\n' + ' cannot be used to form numbers in base 10, like the ' + 'Kharosthi\n' + ' numbers. Formally, a digit is a character that has t= he ' + 'property\n' + ' value Numeric_Type=3DDigit or Numeric_Type=3DDecimal.= \n' '\n' 'str.isidentifier()\n' '\n' - ' Return true if the string is a valid identifier ' + ' Return "True" if the string is a valid identifier ' 'according to the\n' ' language definition, section Identifiers and keywords= .\n' '\n' @@ -9978,32 +10062,33 @@ '\n' 'str.islower()\n' '\n' - ' Return true if all cased characters [4] in the string= ' - 'are lowercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' + ' Return "True" if all cased characters [4] in the stri= ng ' + 'are\n' + ' lowercase and there is at least one cased character, ' + '"False"\n' + ' otherwise.\n' '\n' 'str.isnumeric()\n' '\n' - ' Return true if all characters in the string are numer= ic ' - 'characters,\n' - ' and there is at least one character, false otherwise.= ' - 'Numeric\n' - ' characters include digit characters, and all characte= rs ' - 'that have\n' - ' the Unicode numeric value property, e.g. U+2155, VULG= AR ' - 'FRACTION\n' - ' ONE FIFTH. Formally, numeric characters are those wi= th ' - 'the\n' - ' property value Numeric_Type=3DDigit, Numeric_Type=3DD= ecimal ' - 'or\n' + ' Return "True" if all characters in the string are ' + 'numeric\n' + ' characters, and there is at least one character, ' + '"False" otherwise.\n' + ' Numeric characters include digit characters, and all ' + 'characters\n' + ' that have the Unicode numeric value property, e.g. ' + 'U+2155, VULGAR\n' + ' FRACTION ONE FIFTH. Formally, numeric characters are= ' + 'those with\n' + ' the property value Numeric_Type=3DDigit, ' + 'Numeric_Type=3DDecimal or\n' ' Numeric_Type=3DNumeric.\n' '\n' 'str.isprintable()\n' '\n' - ' Return true if all characters in the string are ' + ' Return "True" if all characters in the string are ' 'printable or the\n' - ' string is empty, false otherwise. Nonprintable ' + ' string is empty, "False" otherwise. Nonprintable ' 'characters are\n' ' those characters defined in the Unicode character ' 'database as\n' @@ -10019,32 +10104,45 @@ '\n' 'str.isspace()\n' '\n' - ' Return true if there are only whitespace characters i= n ' - 'the string\n' - ' and there is at least one character, false otherwise.= ' - 'Whitespace\n' - ' characters are those characters defined in the Unico= de ' - 'character\n' - ' database as =E2=80=9COther=E2=80=9D or =E2=80=9CSepar= ator=E2=80=9D and those with ' - 'bidirectional\n' - ' property being one of =E2=80=9CWS=E2=80=9D, =E2=80=9C= B=E2=80=9D, or =E2=80=9CS=E2=80=9D.\n' + ' Return "True" if there are only whitespace characters= ' + 'in the string\n' + ' and there is at least one character, "False" ' + 'otherwise.\n' + '\n' + ' A character is *whitespace* if in the Unicode charact= er ' + 'database\n' + ' (see "unicodedata"), either its general category is ' + '"Zs"\n' + ' (=E2=80=9CSeparator, space=E2=80=9D), or its bidirect= ional class is one ' + 'of "WS",\n' + ' "B", or "S".\n' '\n' 'str.istitle()\n' '\n' - ' Return true if the string is a titlecased string and ' + ' Return "True" if the string is a titlecased string an= d ' 'there is at\n' ' least one character, for example uppercase characters= ' 'may only\n' ' follow uncased characters and lowercase characters on= ly ' 'cased ones.\n' - ' Return false otherwise.\n' + ' Return "False" otherwise.\n' '\n' 'str.isupper()\n' '\n' - ' Return true if all cased characters [4] in the string= ' - 'are uppercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' + ' Return "True" if all cased characters [4] in the stri= ng ' + 'are\n' + ' uppercase and there is at least one cased character, ' + '"False"\n' + ' otherwise.\n' + '\n' + " >>> 'BANANA'.isupper()\n" + ' True\n' + " >>> 'banana'.isupper()\n" + ' False\n' + " >>> 'baNana'.isupper()\n" + ' False\n' + " >>> ' '.isupper()\n" + ' False\n' '\n' 'str.join(iterable)\n' '\n' @@ -10280,7 +10378,7 @@ ' | Representation | ' 'Description |\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' ' | "\\n" | Line ' 'Feed |\n' ' ' @@ -10619,7 +10717,7 @@ '+-------------------+-----------------------------------+------= ---+\n' '| Escape Sequence | Meaning | Notes= ' '|\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' '| "\\newline" | Backslash and newline ignored ' '| |\n' '+-------------------+-----------------------------------+------= ---+\n' @@ -10665,7 +10763,7 @@ '+-------------------+-----------------------------------+------= ---+\n' '| Escape Sequence | Meaning | Notes= ' '|\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' '| "\\N{name}" | Character named *name* in the | ' '(4) |\n' '| | Unicode database | = ' @@ -10716,13 +10814,9 @@ '\n' ' Changed in version 3.6: Unrecognized escape sequences produc= e ' 'a\n' - ' "DeprecationWarning".\n' - '\n' - ' Changed in version 3.8: Unrecognized escape sequences produc= e ' + ' "DeprecationWarning". In a future Python version they will = be ' 'a\n' - ' "SyntaxWarning". In some future version of Python they will= ' - 'be a\n' - ' "SyntaxError".\n' + ' "SyntaxWarning" and eventually a "SyntaxError".\n' '\n' 'Even in a raw literal, quotes can be escaped with a backslash, ' 'but the\n' @@ -11303,7 +11397,7 @@ ' | Attribute | Meaning = ' '| |\n' ' ' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D|\n' ' | "__doc__" | The function=E2=80=99s docume= ntation ' '| Writable |\n' ' | | string, or "None" if = ' @@ -12106,7 +12200,8 @@ " >>> c =3D dict(zip(['one', 'two', 'three'], [1, 2, 3= ]))\n" " >>> d =3D dict([('two', 2), ('one', 1), ('three', 3)= ])\n" " >>> e =3D dict({'three': 3, 'one': 1, 'two': 2})\n" - ' >>> a =3D=3D b =3D=3D c =3D=3D d =3D=3D e\n' + " >>> f =3D dict({'one': 1, 'three': 3}, two=3D2)\n" + ' >>> a =3D=3D b =3D=3D c =3D=3D d =3D=3D e =3D=3D f\n' ' True\n' '\n' ' Providing keyword arguments as in the first example onl= y ' @@ -12119,6 +12214,11 @@ 'therefore,\n' ' custom mapping types should support too):\n' '\n' + ' list(d)\n' + '\n' + ' Return a list of all the keys used in the dictionary= ' + '*d*.\n' + '\n' ' len(d)\n' '\n' ' Return the number of items in the dictionary *d*.\n' @@ -12287,11 +12387,21 @@ 'the\n' ' documentation of view objects.\n' '\n' + ' An equality comparison between one "dict.values()" ' + 'view and\n' + ' another will always return "False". This also applie= s ' + 'when\n' + ' comparing "dict.values()" to itself:\n' + '\n' + " >>> d =3D {'a': 1}\n" + ' >>> d.values() =3D=3D d.values()\n' + ' False\n' + '\n' ' Dictionaries compare equal if and only if they have the= ' 'same "(key,\n' - ' value)" pairs. Order comparisons (=E2=80=98<=E2=80=99, = =E2=80=98<=3D=E2=80=99, =E2=80=98>=3D=E2=80=99, =E2=80=98>=E2=80=99) ' - 'raise\n' - ' "TypeError".\n' + ' value)" pairs (regardless of ordering). Order compariso= ns ' + '(=E2=80=98<=E2=80=99,\n' + ' =E2=80=98<=3D=E2=80=99, =E2=80=98>=3D=E2=80=99, =E2=80= =98>=E2=80=99) raise "TypeError".\n' '\n' ' Dictionaries preserve insertion order. Note that ' 'updating a key\n' @@ -12577,7 +12687,7 @@ '+----------------------------+--------------------------------= --+------------+\n' '| Operation | Result = ' '| Notes |\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D|\n' '| "x in s" | "True" if an item of *s* is = ' '| (1) |\n' '| | equal to *x*, else "False" = ' @@ -12806,7 +12916,7 @@ '+--------------------------------+----------------------------= ------+-----------------------+\n' '| Operation | ' 'Result | Notes |\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' '| "s[i] =3D x" | item *i* of *s* is replac= ed ' 'by | |\n' '| | ' @@ -13268,7 +13378,7 @@ '| Operation | ' 'Result | Notes = ' '|\n' - '+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n' + '|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D|\n' '| "s[i] =3D x" | item *i* of *s* i= s ' 'replaced by | |\n' '| | ' diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst new file mode 100644 index 0000000000000..2c79bcaf41fef --- /dev/null +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -0,0 +1,5772 @@ +.. bpo: 38722 +.. date: 2019-11-18-16-17-56 +.. nonce: x3mECW +.. release date: 2019-11-19 +.. section: Security + +:mod:`runpy` now uses :meth:`io.open_code` to open code files. Patch by +Jason Killen. + +.. + +.. bpo: 38622 +.. date: 2019-11-14-16-13-23 +.. nonce: 3DYkfb +.. section: Security + +Add additional audit events for the :mod:`ctypes` module. + +.. + +.. bpo: 38418 +.. date: 2019-10-08-19-29-55 +.. nonce: QL7s0- +.. section: Security + +Fixes audit event for :func:`os.system` to be named ``os.system``. + +.. + +.. bpo: 38243 +.. date: 2019-09-25-13-21-09 +.. nonce: 1pfz24 +.. section: Security + +Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` when +rendering the document page as HTML. (Contributed by Dong-hee Na in +:issue:`38243`.) + +.. + +.. bpo: 38174 +.. date: 2019-09-23-21-02-46 +.. nonce: MeWuJd +.. section: Security + +Update vendorized expat library version to 2.2.8, which resolves +CVE-2019-15903. + +.. + +.. bpo: 37764 +.. date: 2019-08-27-01-13-05 +.. nonce: qv67PQ +.. section: Security + +Fixes email._header_value_parser.get_unstructured going into an infinite +loop for a specific case in which the email header does not have trailing +whitespace, and the case in which it contains an invalid encoded word. Patch +by Ashwin Ramaswami. + +.. + +.. bpo: 37461 +.. date: 2019-07-16-08-11-00 +.. nonce: 1Ahz7O +.. section: Security + +Fix an infinite loop when parsing specially crafted email headers. Patch by +Abhilash Raj. + +.. + +.. bpo: 37363 +.. date: 2019-07-01-10-31-14 +.. nonce: fSjatj +.. section: Security + +Adds audit events for the range of supported run commands (see +:ref:`using-on-general`). + +.. + +.. bpo: 37463 +.. date: 2019-07-01-08-46-14 +.. nonce: 1CHwjE +.. section: Security + +ssl.match_hostname() no longer accepts IPv4 addresses with additional text +after the address and only quad-dotted notation without trailing +whitespaces. Some inet_aton() implementations ignore whitespace and all data +after whitespace, e.g. '127.0.0.1 whatever'. + +.. + +.. bpo: 37363 +.. date: 2019-06-21-15-58-59 +.. nonce: diouyl +.. section: Security + +Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, +:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, +:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, +:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, +:func:`os.scandir` and :func:`breakpoint`. + +.. + +.. bpo: 37364 +.. date: 2019-06-21-14-42-53 +.. nonce: IIRc2s +.. section: Security + +:func:`io.open_code` is now used when reading :file:`.pth` files. + +.. + +.. bpo: 34631 +.. date: 2019-06-17-09-34-25 +.. nonce: DBfM4j +.. section: Security + +Updated OpenSSL to 1.1.1c in Windows installer + +.. + +.. bpo: 34155 +.. date: 2019-05-04-13-33-37 +.. nonce: MJll68 +.. section: Security + +Fix parsing of invalid email addresses with more than one ``@`` (e.g. +a at b@c.com.) to not return the part before 2nd ``@`` as valid email address. +Patch by maxking & jpic. + +.. + +.. bpo: 38631 +.. date: 2019-11-18-17-10-20 +.. nonce: tRHaAk +.. section: Core and Builtins + +Replace ``Py_FatalError()`` call with a regular :exc:`RuntimeError` +exception in :meth:`float.__getformat__`. + +.. + +.. bpo: 38639 +.. date: 2019-10-30-11-31-47 +.. nonce: 9-vKtO +.. section: Core and Builtins + +Optimized :func:`math.floor()`, :func:`math.ceil()` and :func:`math.trunc()` +for floats. + +.. + +.. bpo: 38640 +.. date: 2019-10-30-11-25-25 +.. nonce: 4sAFh5 +.. section: Core and Builtins + +Fixed a bug in the compiler that was causing to raise in the presence of +break statements and continue statements inside always false while loops. +Patch by Pablo Galindo. + +.. + +.. bpo: 38613 +.. date: 2019-10-29-15-44-24 +.. nonce: V_R3NC +.. section: Core and Builtins + +Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of +``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but +they are almost same performance for now. + +.. + +.. bpo: 28029 +.. date: 2019-10-29-09-38-54 +.. nonce: AmRMEF +.. section: Core and Builtins + +``"".replace("", s, n)`` now returns ``s`` instead of an empty string for +all non-zero ``n``. There are similar changes for :class:`bytes` and +:class:`bytearray` objects. + +.. + +.. bpo: 38535 +.. date: 2019-10-20-12-43-48 +.. nonce: ESMkVN +.. section: Core and Builtins + +Fixed line numbers and column offsets for AST nodes for calls without +arguments in decorators. + +.. + +.. bpo: 38525 +.. date: 2019-10-20-00-36-18 +.. nonce: Vty1cA +.. section: Core and Builtins + +Fix a segmentation fault when using reverse iterators of empty ``dict`` +objects. Patch by Dong-hee Na and Inada Naoki. + +.. + +.. bpo: 38465 +.. date: 2019-10-19-12-44-13 +.. nonce: V1L8c4 +.. section: Core and Builtins + +:class:`bytearray`, :class:`~array.array` and :class:`~mmap.mmap` objects +allow now to export more than 2**31 buffers at a time. + +.. + +.. bpo: 38469 +.. date: 2019-10-13-23-41-38 +.. nonce: 9kmuQj +.. section: Core and Builtins + +Fixed a bug where the scope of named expressions was not being resolved +correctly in the presence of the *global* keyword. Patch by Pablo Galindo. + +.. + +.. bpo: 38437 +.. date: 2019-10-10-20-42-09 +.. nonce: z_0mZp +.. section: Core and Builtins + +Activate the ``GC_DEBUG`` macro for debug builds of the interpreter (when +``Py_DEBUG`` is set). Patch by Pablo Galindo. + +.. + +.. bpo: 38379 +.. date: 2019-10-10-01-41-02 +.. nonce: _q4dhn +.. section: Core and Builtins + +When the garbage collector makes a collection in which some objects +resurrect (they are reachable from outside the isolated cycles after the +finalizers have been executed), do not block the collection of all objects +that are still unreachable. Patch by Pablo Galindo and Tim Peters. + +.. + +.. bpo: 38379 +.. date: 2019-10-09-16-50-52 +.. nonce: oz5qZx +.. section: Core and Builtins + +When cyclic garbage collection (gc) runs finalizers that resurrect +unreachable objects, the current gc run ends, without collecting any cyclic +trash. However, the statistics reported by ``collect()`` and +``get_stats()`` claimed that all cyclic trash found was collected, and that +the resurrected objects were collected. Changed the stats to report that +none were collected. + +.. + +.. bpo: 38392 +.. date: 2019-10-07-22-51-39 +.. nonce: KaXXps +.. section: Core and Builtins + +In debug mode, :c:func:`PyObject_GC_Track` now calls ``tp_traverse()`` of +the object type to ensure that the object is valid: test that objects +visited by ``tp_traverse()`` are valid. + +.. + +.. bpo: 38210 +.. date: 2019-10-06-15-01-57 +.. nonce: Xgc6F_ +.. section: Core and Builtins + +Remove unecessary intersection and update set operation in dictview with +empty set. (Contributed by Dong-hee Na in :issue:`38210`.) + +.. + +.. bpo: 38402 +.. date: 2019-10-05-19-36-16 +.. nonce: EZuzgK +.. section: Core and Builtins + +Check the error from the system's underlying ``crypt`` or ``crypt_r``. + +.. + +.. bpo: 37474 +.. date: 2019-10-01-12-46-30 +.. nonce: cB3se1 +.. section: Core and Builtins + +On FreeBSD, Python no longer calls ``fedisableexcept()`` at startup to +control the floating point control mode. The call became useless since +FreeBSD 6: it became the default mode. + +.. + +.. bpo: 38006 +.. date: 2019-09-30-09-33-21 +.. nonce: UYlJum +.. section: Core and Builtins + +Fix a bug due to the interaction of weakrefs and the cyclic garbage +collector. We must clear any weakrefs in garbage in order to prevent their +callbacks from executing and causing a crash. + +.. + +.. bpo: 38317 +.. date: 2019-09-30-00-56-21 +.. nonce: pmqlIQ +.. section: Core and Builtins + +Fix warnings options priority: ``PyConfig.warnoptions`` has the highest +priority, as stated in the :pep:`587`. + +.. + +.. bpo: 38310 +.. date: 2019-09-28-22-54-25 +.. nonce: YDTbEo +.. section: Core and Builtins + +Predict ``BUILD_MAP_UNPACK_WITH_CALL`` -> ``CALL_FUNCTION_EX`` opcode pairs +in the main interpreter loop. Patch by Brandt Bucher. + +.. + +.. bpo: 36871 +.. date: 2019-09-24-18-45-46 +.. nonce: p47knk +.. section: Core and Builtins + +Improve error handling for the assert_has_calls and assert_has_awaits +methods of mocks. Fixed a bug where any errors encountered while binding the +expected calls to the mock's spec were silently swallowed, leading to +misleading error output. + +.. + +.. bpo: 11410 +.. date: 2019-09-24-05-32-27 +.. nonce: vS182p +.. section: Core and Builtins + +Better control over symbol visibility is provided through use of the +visibility attributes available in gcc >=3D 4.0, provided in a uniform way +across POSIX and Windows. The POSIX build files have been updated to compile +with -fvisibility=3Dhidden, minimising exported symbols. + +.. + +.. bpo: 38219 +.. date: 2019-09-22-13-56-18 +.. nonce: rFl7JD +.. section: Core and Builtins + +Optimized the :class:`dict` constructor and the :meth:`~dict.update` method +for the case when the argument is a dict. + +.. + +.. bpo: 38236 +.. date: 2019-09-20-19-06-23 +.. nonce: eQ0Tmj +.. section: Core and Builtins + +Python now dumps path configuration if it fails to import the Python codecs +of the filesystem and stdio encodings. + +.. + +.. bpo: 38013 +.. date: 2019-09-12-19-50-01 +.. nonce: I7btD0 +.. section: Core and Builtins + +Allow to call ``async_generator_athrow().throw(...)`` even for non-started +async generator helper. It fixes annoying warning at the end of +:func:`asyncio.run` call. + +.. + +.. bpo: 38124 +.. date: 2019-09-12-00-14-01 +.. nonce: n6E0H7 +.. section: Core and Builtins + +Fix an off-by-one error in PyState_AddModule that could cause out-of-bounds +memory access. + +.. + +.. bpo: 38116 +.. date: 2019-09-11-14-49-42 +.. nonce: KDwmwt +.. section: Core and Builtins + +The select module is now PEP-384 compliant and no longer has static state + +.. + +.. bpo: 38113 +.. date: 2019-09-11-14-10-02 +.. nonce: yZXC3P +.. section: Core and Builtins + +ast module updated to PEP-384 and all statics removed + +.. + +.. bpo: 38076 +.. date: 2019-09-09-16-36-37 +.. nonce: C5dVBl +.. section: Core and Builtins + +The struct module is now PEP-384 compatible + +.. + +.. bpo: 38075 +.. date: 2019-09-09-15-59-50 +.. nonce: N8OZKF +.. section: Core and Builtins + +The random module is now PEP-384 compatible + +.. + +.. bpo: 38074 +.. date: 2019-09-09-15-40-57 +.. nonce: MsVbeI +.. section: Core and Builtins + +zlib module made PEP-384 compatible + +.. + +.. bpo: 38073 +.. date: 2019-09-09-15-17-58 +.. nonce: ZoKYOU +.. section: Core and Builtins + +Make pwd extension module PEP-384 compatible + +.. + +.. bpo: 38072 +.. date: 2019-09-09-15-00-42 +.. nonce: Y1xpDO +.. section: Core and Builtins + +grp module made PEP-384 compatible + +.. + +.. bpo: 38069 +.. date: 2019-09-09-14-46-05 +.. nonce: cn8XLv +.. section: Core and Builtins + +Make _posixsubprocess PEP-384 compatible + +.. + +.. bpo: 38071 +.. date: 2019-09-09-14-44-17 +.. nonce: bLwkBJ +.. section: Core and Builtins + +Make termios extension module PEP-384 compatible + +.. + +.. bpo: 38005 +.. date: 2019-09-02-20-00-31 +.. nonce: e7VsTA +.. section: Core and Builtins + +Fixed comparing and creating of InterpreterID and ChannelID. + +.. + +.. bpo: 36946 +.. date: 2019-09-02-16-17-42 +.. nonce: _lAuSR +.. section: Core and Builtins + +Fix possible signed integer overflow when handling slices. Patch by +hongweipeng. + +.. + +.. bpo: 37994 +.. date: 2019-08-31-11-13-25 +.. nonce: Rj6S4j +.. section: Core and Builtins + +Fixed silencing arbitrary errors if an attribute lookup fails in several +sites. Only AttributeError should be silenced. + +.. + +.. bpo: 8425 +.. date: 2019-08-29-01-55-38 +.. nonce: FTq4A8 +.. section: Core and Builtins + +Optimize set difference_update for the case when the other set is much +larger than the base set. (Suggested by Evgeny Kapun with code contributed +by Michele Orr=C3=B9). + +.. + +.. bpo: 37966 +.. date: 2019-08-27-21-21-36 +.. nonce: 5OBLez +.. section: Core and Builtins + +The implementation of :func:`~unicodedata.is_normalized` has been greatly +sped up on strings that aren't normalized, by implementing the full +normalization-quick-check algorithm from the Unicode standard. + +.. + +.. bpo: 37947 +.. date: 2019-08-26-04-09-57 +.. nonce: mzAQtB +.. section: Core and Builtins + +Adjust correctly the recursion level in the symtable generation for named +expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 37812 +.. date: 2019-08-23-22-46-25 +.. nonce: vsWZwS +.. section: Core and Builtins + +The ``CHECK_SMALL_INT`` macro used inside :file:`Object/longobject.c` has +been replaced with an explicit ``return`` at each call site. + +.. + +.. bpo: 37751 +.. date: 2019-08-20-04-36-37 +.. nonce: CSFzUd +.. section: Core and Builtins + +Fix :func:`codecs.lookup` to normalize the encoding name the same way than +:func:`encodings.normalize_encoding`, except that :func:`codecs.lookup` also +converts the name to lower case. + +.. + +.. bpo: 37830 +.. date: 2019-08-17-18-41-59 +.. nonce: fNfMbz +.. section: Core and Builtins + +Fixed compilation of :keyword:`break` and :keyword:`continue` in the +:keyword:`finally` block when the corresponding :keyword:`try` block +contains :keyword:`return` with a non-constant value. + +.. + +.. bpo: 20490 +.. date: 2019-08-15-12-48-36 +.. nonce: -hXeEn +.. section: Core and Builtins + +Improve import error message for partially initialized module on circular +``from`` imports - by Anthony Sottile. + +.. + +.. bpo: 37840 +.. date: 2019-08-13-18-05-20 +.. nonce: elLCci +.. section: Core and Builtins + +Fix handling of negative indices in :c:member:`~PySequenceMethods.sq_item` +of :class:`bytearray`. Patch by Sergey Fedoseev. + +.. + +.. bpo: 37802 +.. date: 2019-08-09-18-28-57 +.. nonce: pKxcAW +.. section: Core and Builtins + +Slightly improve performance of :c:func:`PyLong_FromUnsignedLong`, +:c:func:`PyLong_FromUnsignedLongLong` and :c:func:`PyLong_FromSize_t`. Patch +by Sergey Fedoseev. + +.. + +.. bpo: 37409 +.. date: 2019-08-06-23-39-05 +.. nonce: 1qwzn2 +.. section: Core and Builtins + +Ensure explicit relative imports from interactive sessions and scripts +(having no parent package) always raise ImportError, rather than treating +the current module as the package. Patch by Ben Lewis. + +.. + +.. bpo: 32912 +.. date: 2019-08-06-14-03-59 +.. nonce: UDwSMJ +.. section: Core and Builtins + +Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of +:exc:`DeprecationWarning` for invalid escape sequences in string and bytes +literals. + +.. + +.. bpo: 37757 +.. date: 2019-08-05-14-22-59 +.. nonce: lRv5HX +.. section: Core and Builtins + +:pep:`572`: As described in the PEP, assignment expressions now raise +:exc:`SyntaxError` when their interaction with comprehension scoping results +in an ambiguous target scope. + +The ``TargetScopeError`` subclass originally proposed by the PEP has been +removed in favour of just raising regular syntax errors for the disallowed +cases. + +.. + +.. bpo: 36279 +.. date: 2019-08-04-12-24-18 +.. nonce: 8Zy7jZ +.. section: Core and Builtins + +Fix potential use of uninitialized memory in :func:`os.wait3`. + +.. + +.. bpo: 36311 +.. date: 2019-08-02-15-01-33 +.. nonce: uY5vt- +.. section: Core and Builtins + +Decoding bytes objects larger than 2GiB is faster and no longer fails when a +multibyte characters spans a chunk boundary. + +.. + +.. bpo: 34880 +.. date: 2019-08-01-10-45-51 +.. nonce: u_x_CG +.. section: Core and Builtins + +The :keyword:`assert` statement now works properly if the +:exc:`AssertionError` exception is being shadowed. Patch by Zackery Spytz. + +.. + +.. bpo: 37340 +.. date: 2019-07-25-11-06-57 +.. nonce: 5ktLEg +.. section: Core and Builtins + +Removed object cache (``free_list``) for bound method objects. Temporary +bound method objects are less used than before thanks to the ``LOAD_METHOD`` +opcode and the ``_PyObject_VectorcallMethod`` C API. + +.. + +.. bpo: 37648 +.. date: 2019-07-22-11-05-05 +.. nonce: 6TY2L- +.. section: Core and Builtins + +Fixed minor inconsistency in :meth:`list.__contains__`, +:meth:`tuple.__contains__` and a few other places. The collection's item is +now always at the left and the needle is on the right of ``=3D=3D``. + +.. + +.. bpo: 37444 +.. date: 2019-07-20-22-34-42 +.. nonce: UOd3Xs +.. section: Core and Builtins + +Update differing exception between :meth:`builtins.__import__` and +:meth:`importlib.__import__`. + +.. + +.. bpo: 37619 +.. date: 2019-07-18-11-50-49 +.. nonce: X6Lulo +.. section: Core and Builtins + +When adding a wrapper descriptor from one class to a different class (for +example, setting ``__add__ =3D str.__add__`` on an ``int`` subclass), an +exception is correctly raised when the operator is called. + +.. + +.. bpo: 37593 +.. date: 2019-07-14-23-57-27 +.. nonce: yHSTwH +.. section: Core and Builtins + +Swap the positions of the *posonlyargs* and *args* parameters in the +constructor of :class:`ast.parameters` nodes. + +.. + +.. bpo: 37543 +.. date: 2019-07-10-20-33-53 +.. nonce: EvI19D +.. section: Core and Builtins + +Optimized pymalloc for non PGO build. + +.. + +.. bpo: 37537 +.. date: 2019-07-10-09-56-47 +.. nonce: OkB0wd +.. section: Core and Builtins + +Compute allocated pymalloc blocks inside _Py_GetAllocatedBlocks(). This +slows down _Py_GetAllocatedBlocks() but gives a small speedup to +_PyObject_Malloc() and _PyObject_Free(). + +.. + +.. bpo: 37467 +.. date: 2019-07-01-12-22-44 +.. nonce: u-XyEu +.. section: Core and Builtins + +Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a +bytes string. For example, for a SyntaxError exception where the filename +attribute is a bytes string. + +.. + +.. bpo: 37433 +.. date: 2019-06-27-15-01-14 +.. nonce: amNGqr +.. section: Core and Builtins + +Fix ``SyntaxError`` indicator printing too many spaces for multi-line +strings - by Anthony Sottile. + +.. + +.. bpo: 37417 +.. date: 2019-06-26-18-41-00 +.. nonce: VsZeHL +.. section: Core and Builtins + +:meth:`bytearray.extend` now correctly handles errors that arise during +iteration. Patch by Brandt Bucher. + +.. + +.. bpo: 37414 +.. date: 2019-06-26-17-27-26 +.. nonce: o6Lnbc +.. section: Core and Builtins + +The undocumented ``sys.callstats()`` function has been removed. Since Python +3.7, it was deprecated and always returned ``None``. It required a special +build option ``CALL_PROFILE`` which was already removed in Python 3.7. + +.. + +.. bpo: 37392 +.. date: 2019-06-25-01-45-06 +.. nonce: J3JhIx +.. section: Core and Builtins + +Remove ``sys.getcheckinterval()`` and ``sys.setcheckinterval()`` functions. +They were deprecated since Python 3.2. Use :func:`sys.getswitchinterval` and +:func:`sys.setswitchinterval` instead. Remove also ``check_interval`` field +of the ``PyInterpreterState`` structure. + +.. + +.. bpo: 37388 +.. date: 2019-06-24-21-53-52 +.. nonce: 0XTZmW +.. section: Core and Builtins + +In development mode and in debug build, *encoding* and *errors* arguments +are now checked on string encoding and decoding operations. Examples: +:func:`open`, :meth:`str.encode` and :meth:`bytes.decode`. + +By default, for best performances, the *errors* argument is only checked at +the first encoding/decoding error, and the *encoding* argument is sometimes +ignored for empty strings. + +.. + +.. bpo: 37348 +.. date: 2019-06-23-00-26-30 +.. nonce: pp8P-x +.. section: Core and Builtins + +Optimized decoding short ASCII string with UTF-8 and ascii codecs. +``b"foo".decode()`` is about 15% faster. Patch by Inada Naoki. + +.. + +.. bpo: 24214 +.. date: 2019-06-22-12-45-20 +.. nonce: hIiHeD +.. section: Core and Builtins + +Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 +incremental decoders. + +.. + +.. bpo: 37330 +.. date: 2019-06-18-17-53-06 +.. nonce: wAvHmz +.. section: Core and Builtins + +:func:`open`, :func:`io.open`, :func:`codecs.open` and +:class:`fileinput.FileInput` no longer accept ``'U'`` ("universal newline") +in the file mode. This flag was deprecated since Python 3.3. + +.. + +.. bpo: 35224 +.. date: 2019-06-17-06-03-55 +.. nonce: FHWPGv +.. section: Core and Builtins + +Reverse evaluation order of key: value in dict comprehensions as proposed in +PEP 572. I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. + +.. + +.. bpo: 37316 +.. date: 2019-06-17-03-53-16 +.. nonce: LytDX_ +.. section: Core and Builtins + +Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. + +.. + +.. bpo: 37300 +.. date: 2019-06-16-02-38-25 +.. nonce: WJkgKV +.. section: Core and Builtins + +Remove an unnecssary Py_XINCREF in classobject.c. + +.. + +.. bpo: 37269 +.. date: 2019-06-14-06-32-33 +.. nonce: SjVVAe +.. section: Core and Builtins + +Fix a bug in the peephole optimizer that was not treating correctly constant +conditions with binary operators. Patch by Pablo Galindo. + +.. + +.. bpo: 20443 +.. date: 2019-06-13-12-55-38 +.. nonce: bQWAxg +.. section: Core and Builtins + +Python now gets the absolute path of the script filename specified on the +command line (ex: "python3 script.py"): the __file__ attribute of the +__main__ module and sys.path[0] become an absolute path, rather than a +relative path. + +.. + +.. bpo: 37257 +.. date: 2019-06-13-02-27-12 +.. nonce: IMxDvT +.. section: Core and Builtins + +Python's small object allocator (``obmalloc.c``) now allows (no more than) +one empty arena to remain available for immediate reuse, without returning +it to the OS. This prevents thrashing in simple loops where an arena could +be created and destroyed anew on each iteration. + +.. + +.. bpo: 37231 +.. date: 2019-06-12-14-39-16 +.. nonce: LF41Es +.. section: Core and Builtins + +The dispatching of type slots to special methods (for example calling +``__mul__`` when doing ``x * y``) has been made faster. + +.. + +.. bpo: 36974 +.. date: 2019-06-11-12-59-38 +.. nonce: bVYmSA +.. section: Core and Builtins + +Implemented separate vectorcall functions for every calling convention of +builtin functions and methods. This improves performance for calls. + +.. + +.. bpo: 37213 +.. date: 2019-06-11-11-15-19 +.. nonce: UPii5K +.. section: Core and Builtins + +Handle correctly negative line offsets in the peephole optimizer. Patch by +Pablo Galindo. + +.. + +.. bpo: 37219 +.. date: 2019-06-10-23-18-31 +.. nonce: jPSufq +.. section: Core and Builtins + +Remove erroneous optimization for empty set differences. + +.. + +.. bpo: 15913 +.. date: 2019-06-06-20-52-38 +.. nonce: 5Sg5cv +.. section: Core and Builtins + +Implement :c:func:`PyBuffer_SizeFromFormat()` function (previously +documented but not implemented): call :func:`struct.calcsize`. Patch by +Joannah Nanjekye. + +.. + +.. bpo: 36922 +.. date: 2019-06-06-13-59-52 +.. nonce: EMZ3TF +.. section: Core and Builtins + +Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` +instead of only instances of ``function``. + +.. + +.. bpo: 36974 +.. date: 2019-06-06-11-00-55 +.. nonce: wdzzym +.. section: Core and Builtins + +The slot ``tp_vectorcall_offset`` is inherited unconditionally to support +``super().__call__()`` when the base class uses vectorcall. + +.. + +.. bpo: 37160 +.. date: 2019-06-05-09-24-17 +.. nonce: O3IAY3 +.. section: Core and Builtins + +:func:`threading.get_native_id` now also supports NetBSD. + +.. + +.. bpo: 37077 +.. date: 2019-05-28-11-47-44 +.. nonce: S1h0Fc +.. section: Core and Builtins + +Add :func:`threading.get_native_id` support for AIX. Patch by M. Felt + +.. + +.. bpo: 36781 +.. date: 2019-05-06-09-59-31 +.. nonce: uocWt6 +.. section: Core and Builtins + +:func:`sum` has been optimized for boolean values. + +.. + +.. bpo: 34556 +.. date: 2019-05-05-18-09-40 +.. nonce: o9kfpu +.. section: Core and Builtins + +Add ``--upgrade-deps`` to venv module. Patch by Cooper Ry Lees + +.. + +.. bpo: 20523 +.. date: 2019-02-15-20-42-36 +.. nonce: rRLrvr +.. section: Core and Builtins + +``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper and Dan +Lidral-Porter. + +.. + +.. bpo: 35551 +.. date: 2019-01-18-16-16-27 +.. nonce: oF5pbO +.. section: Core and Builtins + +Updated encodings: - Removed the "tis260" encoding, which was an alias for +the nonexistent "tactis" codec. - Added "mac_centeuro" as an alias for the +mac_latin2 encoding. + +.. + +.. bpo: 19072 +.. date: 2018-07-23-13-09-54 +.. nonce: Gc59GS +.. section: Core and Builtins + +The :class:`classmethod` decorator can now wrap other descriptors such as +property objects. Adapted from a patch written by Graham Dumpleton. + +.. + +.. bpo: 27575 +.. date: 2018-06-14-13-55-45 +.. nonce: mMYgzv +.. section: Core and Builtins + +Improve speed of dictview intersection by directly using set intersection +logic. Patch by David Su. + +.. + +.. bpo: 30773 +.. date: 2018-06-07-01-01-20 +.. nonce: C31rVE +.. section: Core and Builtins + +Prohibit parallel running of aclose() / asend() / athrow(). Fix ag_running +to reflect the actual running status of the AG. + +.. + +.. bpo: 36589 +.. date: 2019-11-16-22-56-51 +.. nonce: 0Io76D +.. section: Library + +The :func:`curses.update_lines_cols` function now returns ``None`` instead +of ``1`` on success. + +.. + +.. bpo: 38807 +.. date: 2019-11-15-09-30-29 +.. nonce: PsmRog +.. section: Library + +Update :exc:`TypeError` messages for :meth:`os.path.join` to include +:class:`os.PathLike` objects as acceptable input types. + +.. + +.. bpo: 38724 +.. date: 2019-11-14-14-13-29 +.. nonce: T5ySfR +.. section: Library + +Add a repr for ``subprocess.Popen`` objects. Patch by Andrey Doroschenko. + +.. + +.. bpo: 38786 +.. date: 2019-11-13-16-49-03 +.. nonce: gNOwKh +.. section: Library + +pydoc now recognizes and parses HTTPS URLs. Patch by python273. + +.. + +.. bpo: 38785 +.. date: 2019-11-13-16-17-43 +.. nonce: NEOEfk +.. section: Library + +Prevent asyncio from crashing if parent ``__init__`` is not called from a +constructor of object derived from ``asyncio.Future``. + +.. + +.. bpo: 38723 +.. date: 2019-11-12-15-46-28 +.. nonce: gcdMFn +.. section: Library + +:mod:`pdb` now uses :meth:`io.open_code` to trigger auditing events. + +.. + +.. bpo: 27805 +.. date: 2019-11-11-21-43-06 +.. nonce: D3zl1_ +.. section: Library + +Allow opening pipes and other non-seekable files in append mode with +:func:`open`. + +.. + +.. bpo: 38438 +.. date: 2019-11-11-06-14-25 +.. nonce: vSVeHN +.. section: Library + +Simplify the :mod:`argparse` usage message for ``nargs=3D"*"``. + +.. + +.. bpo: 38761 +.. date: 2019-11-10-13-40-33 +.. nonce: P1UUIZ +.. section: Library + +WeakSet is now registered as a collections.abc.MutableSet. + +.. + +.. bpo: 38716 +.. date: 2019-11-06-15-58-07 +.. nonce: R3uMLT +.. section: Library + +logging: change RotatingHandler namer and rotator to class-level attributes. +This stops __init__ from setting them to None in the case where a subclass +defines them with eponymous methods. + +.. + +.. bpo: 38713 +.. date: 2019-11-05-21-22-22 +.. nonce: bmhquU +.. section: Library + +Add :data:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to +wait on a Linux process file descriptor. + +.. + +.. bpo: 38692 +.. date: 2019-11-05-19-15-57 +.. nonce: 2DCDA- +.. section: Library + +Add :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher +implementation that polls process file descriptors. + +.. + +.. bpo: 38692 +.. date: 2019-11-05-07-18-24 +.. nonce: UpatA7 +.. section: Library + +Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`. + +.. + +.. bpo: 38602 +.. date: 2019-10-27-22-29-45 +.. nonce: 7jvYFA +.. section: Library + +Added constants :data:`~fcntl.F_OFD_GETLK`, :data:`~fcntl.F_OFD_SETLK` and +:data:`~fcntl.F_OFD_SETLKW` to the :mod:`fcntl` module. Patch by Dong-hee +Na. + +.. + +.. bpo: 38334 +.. date: 2019-10-27-00-08-49 +.. nonce: pfLLmc +.. section: Library + +Fixed seeking backward on an encrypted :class:`zipfile.ZipExtFile`. + +.. + +.. bpo: 38312 +.. date: 2019-10-26-14-42-20 +.. nonce: e_FVWh +.. section: Library + +Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, +:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions - by +Anthony Sottile. + +.. + +.. bpo: 38586 +.. date: 2019-10-24-17-26-39 +.. nonce: cyq5nr +.. section: Library + +Now :func:`~logging.config.fileConfig` correcty sets the .name of handlers +loaded. + +.. + +.. bpo: 38565 +.. date: 2019-10-24-08-10-30 +.. nonce: SWSUst +.. section: Library + +Add new cache_parameters() method for functools.lru_cache() to better +support pickling. + +.. + +.. bpo: 34679 +.. date: 2019-10-23-16-25-12 +.. nonce: Bnw8o3 +.. section: Library + +asynci.ProactorEventLoop.close() now only calls signal.set_wakeup_fd() in +the main thread. + +.. + +.. bpo: 31202 +.. date: 2019-10-20-12-04-48 +.. nonce: NfdIus +.. section: Library + +The case the result of :func:`pathlib.WindowsPath.glob` matches now the case +of the pattern for literal parts. + +.. + +.. bpo: 36321 +.. date: 2019-10-19-21-41-20 +.. nonce: CFlxfy +.. section: Library + +Remove misspelled attribute. The 3.8 changelog noted that this would be +removed in 3.9. + +.. + +.. bpo: 38521 +.. date: 2019-10-18-13-57-31 +.. nonce: U-7aaM +.. section: Library + +Fixed erroneous equality comparison in statistics.NormalDist(). + +.. + +.. bpo: 38493 +.. date: 2019-10-16-19-56-51 +.. nonce: 86ExWB +.. section: Library + +Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for +:attr:`si_code`. Patch by Dong-hee Na. + +.. + +.. bpo: 38478 +.. date: 2019-10-15-11-37-57 +.. nonce: A87OPO +.. section: Library + +Fixed a bug in :meth:`inspect.signature.bind` that was causing it to fail +when handling a keyword argument with same name as positional-only +parameter. Patch by Pablo Galindo. + +.. + +.. bpo: 33604 +.. date: 2019-10-15-09-47-40 +.. nonce: J12cWT +.. section: Library + +Fixed `hmac.new` and `hmac.HMAC` to raise TypeError instead of ValueError +when the digestmod parameter, now required in 3.8, is omitted. Also +clarified the hmac module documentation and docstrings. + +.. + +.. bpo: 38378 +.. date: 2019-10-13-11-00-03 +.. nonce: yYNpSm +.. section: Library + +Parameters *out* and *in* of :func:`os.sendfile` was renamed to *out_fd* and +*in_fd*. + +.. + +.. bpo: 38417 +.. date: 2019-10-12-00-13-47 +.. nonce: W7x_aS +.. section: Library + +Added support for setting the umask in the child process to the subprocess +module on POSIX systems. + +.. + +.. bpo: 38449 +.. date: 2019-10-11-18-49-00 +.. nonce: 9TWMlz +.. section: Library + +Revert GH-15522, which introduces a regression in +:meth:`mimetypes.guess_type` due to improper handling of filenames as urls. + +.. + +.. bpo: 38431 +.. date: 2019-10-10-16-53-00 +.. nonce: d5wzNp +.. section: Library + +Fix ``__repr__`` method for :class:`dataclasses.InitVar` to support typing +objects, patch by Samuel Colvin. + +.. + +.. bpo: 38109 +.. date: 2019-10-10-00-25-28 +.. nonce: 9w-IGF +.. section: Library + +Add missing :data:`stat.S_IFDOOR`, :data:`stat.S_IFPORT`, +:data:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and +:func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. + +.. + +.. bpo: 38422 +.. date: 2019-10-09-18-16-51 +.. nonce: aiM5bq +.. section: Library + +Clarify docstrings of pathlib suffix(es) + +.. + +.. bpo: 38405 +.. date: 2019-10-08-11-18-40 +.. nonce: 0-7e7s +.. section: Library + +Nested subclasses of :class:`typing.NamedTuple` are now pickleable. + +.. + +.. bpo: 38332 +.. date: 2019-10-05-02-07-52 +.. nonce: hwrPN7 +.. section: Library + +Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` when given +an encoded-word with invalid content-type encoding from propagating all the +way to :func:`email.message.get`. + +.. + +.. bpo: 38371 +.. date: 2019-10-04-18-39-59 +.. nonce: S6Klvm +.. section: Library + +Deprecated the ``split()`` method in :class:`_tkinter.TkappType` in favour +of the ``splitlist()`` method which has more consistent and predicable +behavior. + +.. + +.. bpo: 38341 +.. date: 2019-10-01-21-06-18 +.. nonce: uqwgU_ +.. section: Library + +Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` exported +names. + +.. + +.. bpo: 38319 +.. date: 2019-09-30-22-06-33 +.. nonce: 5QjiDa +.. section: Library + +sendfile() used in socket and shutil modules was raising OverflowError for +files >=3D 2GiB on 32-bit architectures. (patch by Giampaolo Rodola) + +.. + +.. bpo: 38242 +.. date: 2019-09-30-00-15-27 +.. nonce: uPIyAc +.. section: Library + +Revert the new asyncio Streams API + +.. + +.. bpo: 13153 +.. date: 2019-09-29-22-47-37 +.. nonce: 0mO9qR +.. section: Library + +OS native encoding is now used for converting between Python strings and Tcl +objects. This allows to display, copy and paste to clipboard emoji and +other non-BMP characters. Converting strings from Tcl to Python and back +now never fails (except MemoryError). + +.. + +.. bpo: 38019 +.. date: 2019-09-29-13-50-24 +.. nonce: 6MoOE3 +.. section: Library + +Correctly handle pause/resume reading of closed asyncio unix pipe. + +.. + +.. bpo: 38163 +.. date: 2019-09-28-20-16-40 +.. nonce: x51-vK +.. section: Library + +Child mocks will now detect their type as either synchronous or +asynchronous, asynchronous child mocks will be AsyncMocks and synchronous +child mocks will be either MagicMock or Mock (depending on their parent +type). + +.. + +.. bpo: 38161 +.. date: 2019-09-27-16-31-28 +.. nonce: zehai1 +.. section: Library + +Removes _AwaitEvent from AsyncMock. + +.. + +.. bpo: 38216 +.. date: 2019-09-27-15-24-45 +.. nonce: -7yvZR +.. section: Library + +Allow the rare code that wants to send invalid http requests from the +`http.client` library a way to do so. The fixes for bpo-30458 led to +breakage for some projects that were relying on this ability to test their +own behavior in the face of bad requests. + +.. + +.. bpo: 28286 +.. date: 2019-09-26-12-16-30 +.. nonce: LdSsrN +.. section: Library + +Deprecate opening :class:`~gzip.GzipFile` for writing implicitly. Always +specify the *mode* argument for writing. + +.. + +.. bpo: 38108 +.. date: 2019-09-25-21-37-02 +.. nonce: Jr9HU6 +.. section: Library + +Any synchronous magic methods on an AsyncMock now return a MagicMock. Any +asynchronous magic methods on a MagicMock now return an AsyncMock. + +.. + +.. bpo: 38265 +.. date: 2019-09-25-05-16-19 +.. nonce: X6-gsT +.. section: Library + +Update the *length* parameter of :func:`os.pread` to accept +:c:type:`Py_ssize_t` instead of :c:type:`int`. + +.. + +.. bpo: 38112 +.. date: 2019-09-24-10-55-01 +.. nonce: 2EinX9 +.. section: Library + +:mod:`compileall` has a higher default recursion limit and new command-line +arguments for path manipulation, symlinks handling, and multiple +optimization levels. + +.. + +.. bpo: 38248 +.. date: 2019-09-22-13-05-36 +.. nonce: Yo3N_1 +.. section: Library + +asyncio: Fix inconsistent immediate Task cancellation + +.. + +.. bpo: 38237 +.. date: 2019-09-20-14-27-17 +.. nonce: xRUZbx +.. section: Library + +The arguments for the builtin pow function are more descriptive. They can +now also be passed in as keywords. + +.. + +.. bpo: 34002 +.. date: 2019-09-19-19-58-33 +.. nonce: KBnaVX +.. section: Library + +Improve efficiency in parts of email package by changing while-pop to a for +loop, using isdisjoint instead of set intersections. + +.. + +.. bpo: 38191 +.. date: 2019-09-17-12-28-27 +.. nonce: 1TU0HV +.. section: Library + +Constructors of :class:`~typing.NamedTuple` and :class:`~typing.TypedDict` +types now accept arbitrary keyword argument names, including "cls", "self", +"typename", "_typename", "fields" and "_fields". + +.. + +.. bpo: 38155 +.. date: 2019-09-16-21-47-48 +.. nonce: d92lRc +.. section: Library + +Add ``__all__`` to :mod:`datetime`. Patch by Tahia Khan. + +.. + +.. bpo: 38185 +.. date: 2019-09-16-19-12-57 +.. nonce: zYWppY +.. section: Library + +Fixed case-insensitive string comparison in :class:`sqlite3.Row` indexing. + +.. + +.. bpo: 38136 +.. date: 2019-09-16-09-54-42 +.. nonce: MdI-Zb +.. section: Library + +Changes AsyncMock call count and await count to be two different counters. +Now await count only counts when a coroutine has been awaited, not when it +has been called, and vice-versa. Update the documentation around this. + +.. + +.. bpo: 37828 +.. date: 2019-09-15-21-31-18 +.. nonce: gLLDX7 +.. section: Library + +Fix default mock name in :meth:`unittest.mock.Mock.assert_called` +exceptions. Patch by Abraham Toriz Cruz. + +.. + +.. bpo: 38175 +.. date: 2019-09-15-10-30-33 +.. nonce: 61XlUv +.. section: Library + +Fix a memory leak in comparison of :class:`sqlite3.Row` objects. + +.. + +.. bpo: 33936 +.. date: 2019-09-14-10-34-00 +.. nonce: 8wCI_n +.. section: Library + +_hashlib no longer calls obsolete OpenSSL initialization function with +OpenSSL 1.1.0+. + +.. + +.. bpo: 34706 +.. date: 2019-09-13-14-54-33 +.. nonce: HWVpOY +.. section: Library + +Preserve subclassing in inspect.Signature.from_callable. + +.. + +.. bpo: 38153 +.. date: 2019-09-13-12-18-51 +.. nonce: nHAbuJ +.. section: Library + +Names of hashing algorithms frome OpenSSL are now normalized to follow +Python's naming conventions. For example OpenSSL uses sha3-512 instead of +sha3_512 or blake2b512 instead of blake2b. + +.. + +.. bpo: 38115 +.. date: 2019-09-13-09-24-58 +.. nonce: BOO-Y1 +.. section: Library + +Fix a bug in dis.findlinestarts() where it would return invalid bytecode +offsets. Document that a code object's co_lnotab can contain invalid +bytecode offsets. + +.. + +.. bpo: 38148 +.. date: 2019-09-13-08-55-43 +.. nonce: Lnww6D +.. section: Library + +Add slots to :mod:`asyncio` transport classes, which can reduce memory +usage. + +.. + +.. bpo: 38142 +.. date: 2019-09-12-18-41-35 +.. nonce: 1I0Ch0 +.. section: Library + +The _hashlib OpenSSL wrapper extension module is now PEP-384 compliant. + +.. + +.. bpo: 9216 +.. date: 2019-09-12-14-54-45 +.. nonce: W7QMpC +.. section: Library + +hashlib constructors now support usedforsecurity flag to signal that a +hashing algorithm is not used in a security context. + +.. + +.. bpo: 36991 +.. date: 2019-09-12-14-52-38 +.. nonce: 1OcSm8 +.. section: Library + +Fixes a potential incorrect AttributeError exception escaping +ZipFile.extract() in some unsupported input error situations. + +.. + +.. bpo: 38134 +.. date: 2019-09-12-13-18-55 +.. nonce: gXJTbP +.. section: Library + +Remove obsolete copy of PBKDF2_HMAC_fast. All supported OpenSSL versions +contain a fast implementation. + +.. + +.. bpo: 38132 +.. date: 2019-09-12-12-47-35 +.. nonce: KSFx1F +.. section: Library + +The OpenSSL hashlib wrapper uses a simpler implementation. Several Macros +and pointless caches are gone. The hash name now comes from OpenSSL's EVP. +The algorithm name stays the same, except it is now always lower case. + +.. + +.. bpo: 38008 +.. date: 2019-09-12-10-47-34 +.. nonce: sH74Iy +.. section: Library + +Fix parent class check in protocols to correctly identify the module that +provides a builtin protocol, instead of assuming they all come from the +:mod:`collections.abc` module + +.. + +.. bpo: 34037 +.. date: 2019-09-11-21-38-41 +.. nonce: LIAS_3 +.. section: Library + +For :mod:`asyncio`, add a new coroutine +:meth:`loop.shutdown_default_executor`. The new coroutine provides an API to +schedule an executor shutdown that waits on the threadpool to finish +closing. Also, :func:`asyncio.run` has been updated to utilize the new +coroutine. Patch by Kyle Stanley. + +.. + +.. bpo: 37405 +.. date: 2019-09-11-20-27-41 +.. nonce: MG5xiY +.. section: Library + +Fixed regression bug for socket.getsockname() for non-CAN_ISOTP AF_CAN +address family sockets by returning a 1-tuple instead of string. + +.. + +.. bpo: 38121 +.. date: 2019-09-11-16-54-57 +.. nonce: SrSDzB +.. section: Library + +Update parameter names on functions in importlib.metadata matching the +changes in the 0.22 release of importlib_metadata. + +.. + +.. bpo: 38110 +.. date: 2019-09-11-14-49-20 +.. nonce: A19Y-q +.. section: Library + +The os.closewalk() implementation now uses the libc fdwalk() API on +platforms where it is available. + +.. + +.. bpo: 38093 +.. date: 2019-09-11-14-45-30 +.. nonce: yQ6k7y +.. section: Library + +Fixes AsyncMock so it doesn't crash when used with AsyncContextManagers or +AsyncIterators. + +.. + +.. bpo: 37488 +.. date: 2019-09-11-11-44-16 +.. nonce: S8CJUL +.. section: Library + +Add warning to :meth:`datetime.utctimetuple`, :meth:`datetime.utcnow` and +:meth:`datetime.utcfromtimestamp` . + +.. + +.. bpo: 35640 +.. date: 2019-09-10-15-52-55 +.. nonce: X0lp5f +.. section: Library + +Allow passing a :term:`path-like object` as ``directory`` argument to the +:class:`http.server.SimpleHTTPRequestHandler` class. Patch by G=C3=A9ry Ogam. + +.. + +.. bpo: 38086 +.. date: 2019-09-10-11-42-59 +.. nonce: w5TlG- +.. section: Library + +Update importlib.metadata with changes from `importlib_metadata 0.21 +`_. + +.. + +.. bpo: 37251 +.. date: 2019-09-10-10-59-50 +.. nonce: 8zn2o3 +.. section: Library + +Remove `__code__` check in AsyncMock that incorrectly evaluated function +specs as async objects but failed to evaluate classes with `__await__` but +no `__code__` attribute defined as async objects. + +.. + +.. bpo: 38037 +.. date: 2019-09-09-18-39-23 +.. nonce: B0UgFU +.. section: Library + +Fix reference counters in the :mod:`signal` module. + +.. + +.. bpo: 38066 +.. date: 2019-09-09-14-39-47 +.. nonce: l9mWv- +.. section: Library + +Hide internal asyncio.Stream methods: feed_eof(), feed_data(), +set_exception() and set_transport(). + +.. + +.. bpo: 38059 +.. date: 2019-09-08-11-36-50 +.. nonce: 8SA6co +.. section: Library + +inspect.py now uses sys.exit() instead of exit() + +.. + +.. bpo: 38049 +.. date: 2019-09-07-12-32-50 +.. nonce: xKP4tf +.. section: Library + +Added command-line interface for the :mod:`ast` module. + +.. + +.. bpo: 37953 +.. date: 2019-09-06-17-40-34 +.. nonce: db5FQq +.. section: Library + +In :mod:`typing`, improved the ``__hash__`` and ``__eq__`` methods for +:class:`ForwardReferences`. + +.. + +.. bpo: 38026 +.. date: 2019-09-04-20-34-14 +.. nonce: 0LLRX- +.. section: Library + +Fixed :func:`inspect.getattr_static` used ``isinstance`` while it should +avoid dynamic lookup. + +.. + +.. bpo: 35923 +.. date: 2019-09-03-01-41-35 +.. nonce: lYpKbY +.. section: Library + +Update :class:`importlib.machinery.BuiltinImporter` to use +``loader._ORIGIN`` instead of a hardcoded value. Patch by Dong-hee Na. + +.. + +.. bpo: 38010 +.. date: 2019-09-02-14-30-39 +.. nonce: JOnz9Z +.. section: Library + +In ``importlib.metadata`` sync with ``importlib_metadata`` 0.20, clarifying +behavior of ``files()`` and fixing issue where only one requirement was +returned for ``requires()`` on ``dist-info`` packages. + +.. + +.. bpo: 38006 +.. date: 2019-09-02-13-37-27 +.. nonce: Y7vA0Q +.. section: Library + +weakref.WeakValueDictionary defines a local remove() function used as +callback for weak references. This function was created with a closure. +Modify the implementation to avoid the closure. + +.. + +.. bpo: 37995 +.. date: 2019-08-31-13-36-09 +.. nonce: rS8HzT +.. section: Library + +Added the *indent* option to :func:`ast.dump` which allows it to produce a +multiline indented output. + +.. + +.. bpo: 34410 +.. date: 2019-08-31-01-52-59 +.. nonce: 7KbWZQ +.. section: Library + +Fixed a crash in the :func:`tee` iterator when re-enter it. RuntimeError is +now raised in this case. + +.. + +.. bpo: 37140 +.. date: 2019-08-30-11-21-10 +.. nonce: cFAX-a +.. section: Library + +Fix a ctypes regression of Python 3.8. When a ctypes.Structure is passed by +copy to a function, ctypes internals created a temporary object which had +the side effect of calling the structure finalizer (__del__) twice. The +Python semantics requires a finalizer to be called exactly once. Fix ctypes +internals to no longer call the finalizer twice. + +.. + +.. bpo: 37587 +.. date: 2019-08-29-18-48-48 +.. nonce: N7TGTC +.. section: Library + +``_json.scanstring`` is now up to 3x faster when there are many backslash +escaped characters in the JSON string. + +.. + +.. bpo: 37834 +.. date: 2019-08-29-16-41-36 +.. nonce: FThnsh +.. section: Library + +Prevent shutil.rmtree exception when built on non-Windows system without fd +system call support, like older versions of macOS. + +.. + +.. bpo: 10978 +.. date: 2019-08-29-01-19-13 +.. nonce: J6FQYY +.. section: Library + +Semaphores and BoundedSemaphores can now release more than one waiting +thread at a time. + +.. + +.. bpo: 37972 +.. date: 2019-08-28-21-40-12 +.. nonce: kP-n4L +.. section: Library + +Subscripts to the `unittest.mock.call` objects now receive the same chaining +mechanism as any other custom attributes, so that the following usage no +longer raises a `TypeError`: + +call().foo().__getitem__('bar') + +Patch by blhsing + +.. + +.. bpo: 37965 +.. date: 2019-08-28-14-04-18 +.. nonce: 7xGE-C +.. section: Library + +Fix C compiler warning caused by distutils.ccompiler.CCompiler.has_function. + +.. + +.. bpo: 37964 +.. date: 2019-08-27-21-19-28 +.. nonce: SxdnsF +.. section: Library + +Add ``F_GETPATH`` command to :mod:`fcntl`. + +.. + +.. bpo: 37960 +.. date: 2019-08-27-10-52-13 +.. nonce: CTY7Lw +.. section: Library + +``repr()`` of buffered and text streams now silences only expected +exceptions when get the value of "name" and "mode" attributes. + +.. + +.. bpo: 37961 +.. date: 2019-08-27-10-30-44 +.. nonce: 4nm0zZ +.. section: Library + +Add a ``total_nframe`` field to the traces collected by the tracemalloc +module. This field indicates the original number of frames before it was +truncated. + +.. + +.. bpo: 37951 +.. date: 2019-08-27-10-03-48 +.. nonce: MfRQgL +.. section: Library + +Most features of the subprocess module now work again in subinterpreters. +Only *preexec_fn* is restricted in subinterpreters. + +.. + +.. bpo: 36205 +.. date: 2019-08-27-03-53-26 +.. nonce: AfkGRl +.. section: Library + +Fix the rusage implementation of time.process_time() to correctly report the +sum of the system and user CPU time. + +.. + +.. bpo: 37950 +.. date: 2019-08-26-10-45-51 +.. nonce: -K1IKT +.. section: Library + +Fix :func:`ast.dump` when call with incompletely initialized node. + +.. + +.. bpo: 34679 +.. date: 2019-08-25-18-07-48 +.. nonce: HECzL7 +.. section: Library + +Restores instantiation of Windows IOCP event loops from the non-main thread. + +.. + +.. bpo: 36917 +.. date: 2019-08-25-14-56-42 +.. nonce: GBxdw2 +.. section: Library + +Add default implementation of the :meth:`ast.NodeVisitor.visit_Constant` +method which emits a deprecation warning and calls corresponding methody +``visit_Num()``, ``visit_Str()``, etc. + +.. + +.. bpo: 37798 +.. date: 2019-08-24-16-54-49 +.. nonce: 7mRQCk +.. section: Library + +Update test_statistics.py to verify that the statistics module works well +for both C and Python implementations. Patch by Dong-hee Na + +.. + +.. bpo: 26589 +.. date: 2019-08-23-00-55-19 +.. nonce: M1xyxG +.. section: Library + +Added a new status code to the http module: 451 +UNAVAILABLE_FOR_LEGAL_REASONS + +.. + +.. bpo: 37915 +.. date: 2019-08-22-16-13-27 +.. nonce: xyoZI5 +.. section: Library + +Fix a segmentation fault that appeared when comparing instances of +``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo +Galindo. + +.. + +.. bpo: 32554 +.. date: 2019-08-22-01-49-05 +.. nonce: 4xiXyM +.. section: Library + +Deprecate having random.seed() call hash on arbitrary types. + +.. + +.. bpo: 9938 +.. date: 2019-08-21-16-38-56 +.. nonce: t3G7N9 +.. section: Library + +Add optional keyword argument ``exit_on_error`` for :class:`ArgumentParser`. + +.. + +.. bpo: 37851 +.. date: 2019-08-21-13-43-04 +.. nonce: mIIfD_ +.. section: Library + +The :mod:`faulthandler` module no longer allocates its alternative stack at +Python startup. Now the stack is only allocated at the first faulthandler +usage. + +.. + +.. bpo: 32793 +.. date: 2019-08-20-05-17-32 +.. nonce: cgpXl6 +.. section: Library + +Fix a duplicated debug message when :meth:`smtplib.SMTP.connect` is called. + +.. + +.. bpo: 37885 +.. date: 2019-08-19-10-31-41 +.. nonce: 4Nc9sp +.. section: Library + +venv: Don't generate unset variable warning on deactivate. + +.. + +.. bpo: 37868 +.. date: 2019-08-17-22-33-54 +.. nonce: hp64fi +.. section: Library + +Fix dataclasses.is_dataclass when given an instance that never raises +AttributeError in __getattr__. That is, an object that returns something +for __dataclass_fields__ even if it's not a dataclass. + +.. + +.. bpo: 37811 +.. date: 2019-08-14-21-41-07 +.. nonce: d1xYj7 +.. section: Library + +Fix ``socket`` module's ``socket.connect(address)`` function being unable to +establish connection in case of interrupted system call. The problem was +observed on all OSes which ``poll(2)`` system call can take only +non-negative integers and -1 as a timeout value. + +.. + +.. bpo: 37863 +.. date: 2019-08-14-20-46-39 +.. nonce: CkXqgX +.. section: Library + +Optimizations for Fraction.__hash__ suggested by Tim Peters. + +.. + +.. bpo: 21131 +.. date: 2019-08-14-15-34-23 +.. nonce: 0MMQRi +.. section: Library + +Fix ``faulthandler.register(chain=3DTrue)`` stack. faulthandler now allocates +a dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just ``SIGSTKSZ`` +bytes. Calling the previous signal handler in faulthandler signal handler +uses more than ``SIGSTKSZ`` bytes of stack memory on some platforms. + +.. + +.. bpo: 37798 +.. date: 2019-08-14-13-51-24 +.. nonce: AmXrik +.. section: Library + +Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Dong-hee Na + +.. + +.. bpo: 37804 +.. date: 2019-08-12-23-07-47 +.. nonce: Ene6L- +.. section: Library + +Remove the deprecated method `threading.Thread.isAlive()`. Patch by Dong-hee +Na. + +.. + +.. bpo: 37819 +.. date: 2019-08-11-10-34-19 +.. nonce: LVJls- +.. section: Library + +Add Fraction.as_integer_ratio() to match the corresponding methods in bool, +int, float, and decimal. + +.. + +.. bpo: 14465 +.. date: 2019-08-10-18-50-04 +.. nonce: qZGC4g +.. section: Library + +Add an xml.etree.ElementTree.indent() function for pretty-printing XML +trees. Contributed by Stefan Behnel. + +.. + +.. bpo: 37810 +.. date: 2019-08-10-12-33-27 +.. nonce: d4zbvB +.. section: Library + +Fix :mod:`difflib` ``?`` hint in diff output when dealing with tabs. Patch +by Anthony Sottile. + +.. + +.. bpo: 37772 +.. date: 2019-08-07-23-48-09 +.. nonce: hLCvdn +.. section: Library + +In ``zipfile.Path``, when adding implicit dirs, ensure that ancestral +directories are added and that duplicates are excluded. + +.. + +.. bpo: 18578 +.. date: 2019-08-07-19-34-07 +.. nonce: xfvdb_ +.. section: Library + +Renamed and documented `test.bytecode_helper` as +`test.support.bytecode_helper`. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37785 +.. date: 2019-08-07-14-49-22 +.. nonce: y7OlT8 +.. section: Library + +Fix xgettext warnings in :mod:`argparse`. + +.. + +.. bpo: 34488 +.. date: 2019-08-06-21-30-58 +.. nonce: OqxVo8 +.. section: Library + +:meth:`writelines` method of :class:`io.BytesIO` is now slightly faster when +many small lines are passed. Patch by Sergey Fedoseev. + +.. + +.. bpo: 37449 +.. date: 2019-08-04-17-22-33 +.. nonce: ycbL2z +.. section: Library + +`ensurepip` now uses `importlib.resources.read_binary()` to read data +instead of `pkgutil.get_data()`. Patch by Joannah Nanjekye. + +.. + +.. bpo: 28292 +.. date: 2019-08-04-11-47-58 +.. nonce: vkihH5 +.. section: Library + +Mark calendar.py helper functions as being private. The follows PEP 8 +guidance to maintain the style conventions in the module and it addresses a +known case of user confusion. + +.. + +.. bpo: 18049 +.. date: 2019-08-02-16-44-42 +.. nonce: OA4qBL +.. section: Library + +Add definition of THREAD_STACK_SIZE for AIX in Python/thread_pthread.h The +default thread stacksize caused crashes with the default recursion limit +Patch by M Felt + +.. + +.. bpo: 37742 +.. date: 2019-08-02-14-01-25 +.. nonce: f4Xn9S +.. section: Library + +The logging.getLogger() API now returns the root logger when passed the name +'root', whereas previously it returned a non-root logger named 'root'. This +could affect cases where user code explicitly wants a non-root logger named +'root', or instantiates a logger using logging.getLogger(__name__) in some +top-level module called 'root.py'. + +.. + +.. bpo: 37738 +.. date: 2019-08-01-17-11-16 +.. nonce: A3WWcT +.. section: Library + +Fix the implementation of curses ``addch(str, color_pair)``: pass the color +pair to ``setcchar()``, instead of always passing 0 as the color pair. + +.. + +.. bpo: 37723 +.. date: 2019-07-31-16-49-01 +.. nonce: zq6tw8 +.. section: Library + +Fix performance regression on regular expression parsing with huge character +sets. Patch by Yann Vaginay. + +.. + +.. bpo: 35943 +.. date: 2019-07-31-15-52-51 +.. nonce: -KswoB +.. section: Library + +The function :c:func:`PyImport_GetModule` now ensures any module it returns +is fully initialized. Patch by Joannah Nanjekye. + +.. + +.. bpo: 32178 +.. date: 2019-07-30-22-41-05 +.. nonce: X-IFLe +.. section: Library + +Fix IndexError in :mod:`email` package when trying to parse invalid address +fields starting with ``:``. + +.. + +.. bpo: 37268 +.. date: 2019-07-30-01-27-29 +.. nonce: QDmA44 +.. section: Library + +The :mod:`parser` module is deprecated and will be removed in future +versions of Python. + +.. + +.. bpo: 11953 +.. date: 2019-07-29-21-39-45 +.. nonce: 4Hpwf9 +.. section: Library + +Completing WSA* error codes in :mod:`socket`. + +.. + +.. bpo: 37685 +.. date: 2019-07-28-22-25-25 +.. nonce: _3bN9f +.. section: Library + +Fixed comparisons of :class:`datetime.timedelta` and +:class:`datetime.timezone`. + +.. + +.. bpo: 37697 +.. date: 2019-07-28-17-44-21 +.. nonce: 7UV5d0 +.. section: Library + +Syncronize ``importlib.metadata`` with `importlib_metadata 0.19 +`_, +improving handling of EGG-INFO files and fixing a crash when entry point +names contained colons. + +.. + +.. bpo: 37695 +.. date: 2019-07-27-20-21-03 +.. nonce: QANdvg +.. section: Library + +Correct :func:`curses.unget_wch` error message. Patch by Anthony Sottile. + +.. + +.. bpo: 37689 +.. date: 2019-07-27-18-00-43 +.. nonce: glEmZi +.. section: Library + +Add :meth:`is_relative_to` in :class:`PurePath` to determine whether or not +one path is relative to another. + +.. + +.. bpo: 29553 +.. date: 2019-07-27-10-14-45 +.. nonce: TVeIDe +.. section: Library + +Fixed :meth:`argparse.ArgumentParser.format_usage` for mutually exclusive +groups. Patch by Andrew Nester. + +.. + +.. bpo: 37691 +.. date: 2019-07-26-22-30-01 +.. nonce: 1Li3rx +.. section: Library + +Let math.dist() accept coordinates as sequences (or iterables) rather than +just tuples. + +.. + +.. bpo: 37685 +.. date: 2019-07-26-00-12-29 +.. nonce: TqckMZ +.. section: Library + +Fixed ``__eq__``, ``__lt__`` etc implementations in some classes. They now +return :data:`NotImplemented` for unsupported type of the other operand. +This allows the other operand to play role (for example the equality +comparison with :data:`~unittest.mock.ANY` will return ``True``). + +.. + +.. bpo: 37354 +.. date: 2019-07-25-10-28-40 +.. nonce: RT3_3H +.. section: Library + +Make Activate.ps1 Powershell script static to allow for signing it. + +.. + +.. bpo: 37664 +.. date: 2019-07-24-18-27-44 +.. nonce: o-GYZC +.. section: Library + +Update wheels bundled with ensurepip (pip 19.2.3 and setuptools 41.2.0) + +.. + +.. bpo: 37663 +.. date: 2019-07-24-14-38-53 +.. nonce: h4-9-1 +.. section: Library + +Bring consistency to venv shell activation scripts by always using +__VENV_PROMPT__. + +.. + +.. bpo: 37642 +.. date: 2019-07-21-20-59-31 +.. nonce: L61Bvy +.. section: Library + +Allowed the pure Python implementation of :class:`datetime.timezone` to +represent sub-minute offsets close to minimum and maximum boundaries, +specifically in the ranges (23:59, 24:00) and (-23:59, 24:00). Patch by +Ngalim Siregar + +.. + +.. bpo: 36161 +.. date: 2019-07-20-01-17-43 +.. nonce: Fzf-f9 +.. section: Library + +In :mod:`posix`, use ``ttyname_r`` instead of ``ttyname`` for thread safety. + +.. + +.. bpo: 36324 +.. date: 2019-07-19-22-44-41 +.. nonce: 1VjywS +.. section: Library + +Make internal attributes for statistics.NormalDist() private. + +.. + +.. bpo: 37555 +.. date: 2019-07-19-20-13-48 +.. nonce: S5am28 +.. section: Library + +Fix `NonCallableMock._call_matcher` returning tuple instead of `_Call` +object when `self._spec_signature` exists. Patch by Elizabeth Uselton + +.. + +.. bpo: 29446 +.. date: 2019-07-19-16-06-48 +.. nonce: iXGuoi +.. section: Library + +Make `from tkinter import *` import only the expected objects. + +.. + +.. bpo: 16970 +.. date: 2019-07-19-01-46-56 +.. nonce: GEASf5 +.. section: Library + +Adding a value error when an invalid value in passed to nargs Patch by +Robert Leenders + +.. + +.. bpo: 34443 +.. date: 2019-07-17-11-10-08 +.. nonce: OFnGqz +.. section: Library + +Exceptions from :mod:`enum` now use the ``__qualname`` of the enum class in +the exception message instead of the ``__name__``. + +.. + +.. bpo: 37491 +.. date: 2019-07-17-06-54-43 +.. nonce: op0aMs +.. section: Library + +Fix ``IndexError`` when parsing email headers with unexpectedly ending +bare-quoted string value. Patch by Abhilash Raj. + +.. + +.. bpo: 37587 +.. date: 2019-07-13-16-02-48 +.. nonce: fd-1aF +.. section: Library + +Make json.loads faster for long strings. (Patch by Marco Paolini) + +.. + +.. bpo: 18378 +.. date: 2019-07-13-13-40-12 +.. nonce: NHcojp +.. section: Library + +Recognize "UTF-8" as a valid value for LC_CTYPE in locale._parse_localename. + +.. + +.. bpo: 37579 +.. date: 2019-07-13-10-59-43 +.. nonce: B1Tq9i +.. section: Library + +Return :exc:`NotImplemented` in Python implementation of ``__eq__`` for +:class:`~datetime.timedelta` and :class:`~datetime.time` when the other +object being compared is not of the same type to match C implementation. +Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 21478 +.. date: 2019-07-10-23-07-11 +.. nonce: cCw9rF +.. section: Library + +Record calls to parent when autospecced object is attached to a mock using +:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37531 +.. date: 2019-07-09-19-38-26 +.. nonce: GX7s8S +.. section: Library + +"python3 -m test -jN --timeout=3DTIMEOUT" now kills a worker process if it +runs longer than *TIMEOUT* seconds. + +.. + +.. bpo: 37482 +.. date: 2019-07-09-11-20-21 +.. nonce: auzvev +.. section: Library + +Fix serialization of display name in originator or destination address +fields with both encoded words and special chars. + +.. + +.. bpo: 36993 +.. date: 2019-07-09-05-44-39 +.. nonce: 4javqu +.. section: Library + +Improve error reporting for corrupt zip files with bad zip64 extra data. +Patch by Daniel Hillier. + +.. + +.. bpo: 37502 +.. date: 2019-07-08-03-15-04 +.. nonce: qZGC4g +.. section: Library + +pickle.loads() no longer raises TypeError when the buffers argument is set +to None + +.. + +.. bpo: 37520 +.. date: 2019-07-07-21-09-08 +.. nonce: Gg0KD6 +.. section: Library + +Correct behavior for zipfile.Path.parent when the path object identifies a +subdirectory. + +.. + +.. bpo: 18374 +.. date: 2019-07-05-21-46-45 +.. nonce: qgE0H3 +.. section: Library + +Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances +which had a too large value in some situations. + +.. + +.. bpo: 37424 +.. date: 2019-07-04-13-00-20 +.. nonce: 0i1MR- +.. section: Library + +Fixes a possible hang when using a timeout on `subprocess.run()` while +capturing output. If the child process spawned its own children or +otherwise connected its stdout or stderr handles with another process, we +could hang after the timeout was reached and our child was killed when +attempting to read final output from the pipes. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-12-47-52 +.. nonce: gR5hC8 +.. section: Library + +Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear also the +'tempdir' configuration of the current process, so next call to +``get_temp_dir()`` will create a new temporary directory, rather than +reusing the removed temporary directory. + +.. + +.. bpo: 37481 +.. date: 2019-07-02-13-08-30 +.. nonce: hd5k09 +.. section: Library + +The distutils ``bdist_wininst`` command is deprecated in Python 3.8, use +``bdist_wheel`` (wheel packages) instead. + +.. + +.. bpo: 37479 +.. date: 2019-07-02-12-43-57 +.. nonce: O53a5S +.. section: Library + +When `Enum.__str__` is overridden in a derived class, the override will be +used by `Enum.__format__` regardless of whether mixin classes are present. + +.. + +.. bpo: 37440 +.. date: 2019-06-28-16-40-17 +.. nonce: t3wX-N +.. section: Library + +http.client now enables TLS 1.3 post-handshake authentication for default +context or if a cert_file is passed to HTTPSConnection. + +.. + +.. bpo: 37437 +.. date: 2019-06-27-20-33-50 +.. nonce: du39_A +.. section: Library + +Update vendorized expat version to 2.2.7. + +.. + +.. bpo: 37428 +.. date: 2019-06-27-13-27-02 +.. nonce: _wcwUd +.. section: Library + +SSLContext.post_handshake_auth =3D True no longer sets +SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the +option is documented as ignored for clients, OpenSSL implicitly enables cert +chain validation when the flag is set. + +.. + +.. bpo: 37420 +.. date: 2019-06-26-22-25-05 +.. nonce: CxFJ09 +.. section: Library + +:func:`os.sched_setaffinity` now correctly handles errors that arise during +iteration over its ``mask`` argument. Patch by Brandt Bucher. + +.. + +.. bpo: 37412 +.. date: 2019-06-26-16-28-59 +.. nonce: lx0VjC +.. section: Library + +The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, +rather than the ANSI code page: see :pep:`529` for the rationale. The +function is no longer deprecated on Windows. + +.. + +.. bpo: 37406 +.. date: 2019-06-26-03-00-06 +.. nonce: uovkpq +.. section: Library + +The sqlite3 module now raises TypeError, rather than ValueError, if +operation argument type is not str: execute(), executemany() and calling a +connection. + +.. + +.. bpo: 29412 +.. date: 2019-06-25-19-27-25 +.. nonce: n4Zqdh +.. section: Library + +Fix IndexError in parsing a header value ending unexpectedly. Patch by +Abhilash Raj. + +.. + +.. bpo: 36546 +.. date: 2019-06-25-05-07-48 +.. nonce: RUcxaK +.. section: Library + +The *dist* argument for statistics.quantiles() is now positional only. The +current name doesn't reflect that the argument can be either a dataset or a +distribution. Marking the parameter as positional avoids confusion and +makes it possible to change the name later. + +.. + +.. bpo: 37394 +.. date: 2019-06-25-02-10-00 +.. nonce: srZ1zx +.. section: Library + +Fix a bug that was causing the :mod:`queue` module to fail if the +accelerator module was not available. Patch by Pablo Galindo. + +.. + +.. bpo: 37376 +.. date: 2019-06-24-11-26-34 +.. nonce: SwSUQ4 +.. section: Library + +:mod:`pprint` now has support for :class:`types.SimpleNamespace`. Patch by +Carl Bordum Hansen. + +.. + +.. bpo: 26967 +.. date: 2019-06-23-12-46-10 +.. nonce: xEuem1 +.. section: Library + +An :class:`~argparse.ArgumentParser` with ``allow_abbrev=3DFalse`` no longer +disables grouping of short flags, such as ``-vv``, but only disables +abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds. + +.. + +.. bpo: 37212 +.. date: 2019-06-22-22-00-35 +.. nonce: Zhv-tq +.. section: Library + +:func:`unittest.mock.call` now preserves the order of keyword arguments in +repr output. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37372 +.. date: 2019-06-22-12-30-00 +.. nonce: kIKqZ6 +.. section: Library + +Fix error unpickling datetime.time objects from Python 2 with seconds>=3D24. +Patch by Justin Blanchard. + +.. + +.. bpo: 37345 +.. date: 2019-06-22-08-51-44 +.. nonce: o8XABX +.. section: Library + +Add formal support for UDPLITE sockets. Support was present before, but it +is now easier to detect support with ``hasattr(socket, 'IPPROTO_UDPLITE')`` +and there are constants defined for each of the values needed: +:py:obj:`socket.IPPROTO_UDPLITE`, :py:obj:`UDPLITE_SEND_CSCOV`, and +:py:obj:`UDPLITE_RECV_CSCOV`. Patch by Gabe Appleton. + +.. + +.. bpo: 37358 +.. date: 2019-06-21-14-54-02 +.. nonce: RsASpn +.. section: Library + +Optimized ``functools.partial`` by using vectorcall. + +.. + +.. bpo: 37347 +.. date: 2019-06-20-14-23-48 +.. nonce: Gf9yYI +.. section: Library + +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` +:meth:`sqlite3.Connection.set_trace_callback` methods lead to segfaults if +some of these methods are called twice with an equal object but not the +same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. + +.. + +.. bpo: 37163 +.. date: 2019-06-19-10-35-53 +.. nonce: 9pPg2F +.. section: Library + +The *obj* argument of :func:`dataclasses.replace` is positional-only now. + +.. + +.. bpo: 37085 +.. date: 2019-06-18-16-29-31 +.. nonce: GeYaD6 +.. section: Library + +Add the optional Linux SocketCAN Broadcast Manager constants, used as flags +to configure the BCM behaviour, in the socket module. Patch by Karl Ding. + +.. + +.. bpo: 37328 +.. date: 2019-06-18-15-31-33 +.. nonce: 2PW1-l +.. section: Library + +``HTMLParser.unescape`` is removed. It was undocumented and deprecated +since Python 3.4. + +.. + +.. bpo: 37305 +.. date: 2019-06-18-13-59-55 +.. nonce: fGzWlP +.. section: Library + +Add .webmanifest -> application/manifest+json to list of recognized file +types and content type headers + +.. + +.. bpo: 37320 +.. date: 2019-06-17-22-10-37 +.. nonce: ffieYa +.. section: Library + +``aifc.openfp()`` alias to ``aifc.open()``, ``sunau.openfp()`` alias to +``sunau.open()``, and ``wave.openfp()`` alias to ``wave.open()`` have been +removed. They were deprecated since Python 3.7. + +.. + +.. bpo: 37315 +.. date: 2019-06-17-11-59-52 +.. nonce: o1xFC0 +.. section: Library + +Deprecated accepting floats with integral value (like ``5.0``) in +:func:`math.factorial`. + +.. + +.. bpo: 37312 +.. date: 2019-06-17-10-03-52 +.. nonce: qKvBfF +.. section: Library + +``_dummy_thread`` and ``dummy_threading`` modules have been removed. These +modules were deprecated since Python 3.7 which requires threading support. + +.. + +.. bpo: 33972 +.. date: 2019-06-15-14-39-50 +.. nonce: XxnNPw +.. section: Library + +Email with single part but content-type set to ``multipart/*`` doesn't raise +AttributeError anymore. + +.. + +.. bpo: 37280 +.. date: 2019-06-14-13-30-47 +.. nonce: Fxur0F +.. section: Library + +Use threadpool for reading from file for sendfile fallback mode. + +.. + +.. bpo: 37279 +.. date: 2019-06-14-13-25-56 +.. nonce: OHlW6l +.. section: Library + +Fix asyncio sendfile support when sendfile sends extra data in fallback +mode. + +.. + +.. bpo: 19865 +.. date: 2019-06-14-08-30-16 +.. nonce: FRGH4I +.. section: Library + +:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters +on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). + +.. + +.. bpo: 37266 +.. date: 2019-06-13-11-59-52 +.. nonce: goLjef +.. section: Library + +In a subinterpreter, spawning a daemon thread now raises an exception. +Daemon threads were never supported in subinterpreters. Previously, the +subinterpreter finalization crashed with a Pyton fatal error if a daemon +thread was still running. + +.. + +.. bpo: 37210 +.. date: 2019-06-12-16-10-50 +.. nonce: r4yMg6 +.. section: Library + +Allow pure Python implementation of :mod:`pickle` to work even when the C +:mod:`_pickle` module is unavailable. + +.. + +.. bpo: 21872 +.. date: 2019-06-12-08-56-22 +.. nonce: V9QGGN +.. section: Library + +Fix :mod:`lzma`: module decompresses data incompletely. When decompressing a +FORMAT_ALONE format file, and it doesn't have the end marker, sometimes the +last one to dozens bytes can't be output. Patch by Ma Lin. + +.. + +.. bpo: 35922 +.. date: 2019-06-11-19-34-29 +.. nonce: rxpzWr +.. section: Library + +Fix :meth:`RobotFileParser.crawl_delay` and +:meth:`RobotFileParser.request_rate` to return ``None`` rather than raise +:exc:`AttributeError` when no relevant rule is defined in the robots.txt +file. Patch by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 35766 +.. date: 2019-06-11-16-41-40 +.. nonce: v1Kj-T +.. section: Library + +Change the format of feature_version to be a (major, minor) tuple. + +.. + +.. bpo: 36607 +.. date: 2019-06-11-13-52-04 +.. nonce: 5_mJkQ +.. section: Library + +Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if +internal tasks weak set is changed by another thread during iteration. + +.. + +.. bpo: 18748 +.. date: 2019-06-11-01-54-19 +.. nonce: ADqCkq +.. section: Library + +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimick :class:`_io.IOBase` finalizer. + +.. + +.. bpo: 36402 +.. date: 2019-06-11-00-35-02 +.. nonce: b0IJVp +.. section: Library + +Fix a race condition at Python shutdown when waiting for threads. Wait until +the Python thread state of all non-daemon threads get deleted (join all +non-daemon threads), rather than just wait until non-daemon Python threads +complete. + +.. + +.. bpo: 37206 +.. date: 2019-06-09-22-25-03 +.. nonce: 2WBg4q +.. section: Library + +Default values which cannot be represented as Python objects no longer +improperly represented as ``None`` in function signatures. + +.. + +.. bpo: 37111 +.. date: 2019-06-09-17-22-33 +.. nonce: 2I0z2k +.. section: Library + +Added ``encoding`` and ``errors`` keyword parameters to +``logging.basicConfig``. + +.. + +.. bpo: 12144 +.. date: 2019-06-08-23-26-58 +.. nonce: Z7mz-q +.. section: Library + +Ensure cookies with ``expires`` attribute are handled in +:meth:`CookieJar.make_cookies`. + +.. + +.. bpo: 34886 +.. date: 2019-06-08-16-03-19 +.. nonce: Ov-pc9 +.. section: Library + +Fix an unintended ValueError from :func:`subprocess.run` when checking for +conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` +args when they were explicitly provided but with `None` values within a +passed in `**kwargs` dict rather than as passed directly by name. Patch +contributed by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 37173 +.. date: 2019-06-08-11-33-48 +.. nonce: 0e_8gS +.. section: Library + +The exception message for ``inspect.getfile()`` now correctly reports the +passed class rather than the builtins module. + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-16-09 +.. nonce: Day_oB +.. section: Library + +Give math.perm() a one argument form that means the same as +math.factorial(). + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-11-34 +.. nonce: b1StSv +.. section: Library + +For math.perm(n, k), let k default to n, giving the same result as +factorial. + +.. + +.. bpo: 37165 +.. date: 2019-06-05-11-48-19 +.. nonce: V_rwfE +.. section: Library + +Converted _collections._count_elements to use the Argument Clinic. + +.. + +.. bpo: 34767 +.. date: 2019-06-04-23-44-52 +.. nonce: BpDShN +.. section: Library + +Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. + +.. + +.. bpo: 37158 +.. date: 2019-06-04-22-25-38 +.. nonce: JKm15S +.. section: Library + +Speed-up statistics.fmean() by switching from a function to a generator. + +.. + +.. bpo: 34282 +.. date: 2019-06-04-15-39-14 +.. nonce: aAK54n +.. section: Library + +Remove ``Enum._convert`` method, deprecated in 3.8. + +.. + +.. bpo: 37150 +.. date: 2019-06-04-14-44-41 +.. nonce: TTzHxj +.. section: Library + +`argparse._ActionsContainer.add_argument` now throws error, if someone +accidentally pass FileType class object instead of instance of FileType as +`type` argument + +.. + +.. bpo: 28724 +.. date: 2019-05-30-15-51-42 +.. nonce: 34TrS8 +.. section: Library + +The socket module now has the :func:`socket.send_fds` and +:func:`socket.recv.fds` methods. Contributed by Joannah Nanjekye, Shinya +Okano and Victor Stinner. + +.. + +.. bpo: 35621 +.. date: 2019-05-28-19-03-46 +.. nonce: Abc1lf +.. section: Library + +Support running asyncio subprocesses when execution event loop in a thread +on UNIX. + +.. + +.. bpo: 36520 +.. date: 2019-05-28-02-37-00 +.. nonce: W4tday +.. section: Library + +Lengthy email headers with UTF-8 characters are now properly encoded when +they are folded. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 30835 +.. date: 2019-05-27-15-29-46 +.. nonce: 3FoaWH +.. section: Library + +Fixed a bug in email parsing where a message with invalid bytes in +content-transfer-encoding of a multipart message can cause an +AttributeError. Patch by Andrew Donnellan. + +.. + +.. bpo: 31163 +.. date: 2019-05-26-16-34-53 +.. nonce: 21A802 +.. section: Library + +pathlib.Path instance's rename and replace methods now return the new Path +instance. + +.. + +.. bpo: 25068 +.. date: 2019-05-22-04-52-35 +.. nonce: vR_rC- +.. section: Library + +:class:`urllib.request.ProxyHandler` now lowercases the keys of the passed +dictionary. + +.. + +.. bpo: 26185 +.. date: 2019-05-20-14-17-29 +.. nonce: pQW4mI +.. section: Library + +Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by Micka=C3=ABl +Schoentgen. + +.. + +.. bpo: 21315 +.. date: 2019-05-19-10-48-46 +.. nonce: PgXVqF +.. section: Library + +Email headers containing RFC2047 encoded words are parsed despite the +missing whitespace, and a defect registered. Also missing trailing +whitespace after encoded words is now registered as a defect. + +.. + +.. bpo: 31904 +.. date: 2019-05-17-16-50-02 +.. nonce: 4a5ggm +.. section: Library + +Port test_datetime to VxWorks: skip zoneinfo tests on VxWorks + +.. + +.. bpo: 35805 +.. date: 2019-05-17-15-11-08 +.. nonce: E4YwYz +.. section: Library + +Add parser for Message-ID header and add it to default HeaderRegistry. This +should prevent folding of Message-ID using RFC 2048 encoded words. + +.. + +.. bpo: 36871 +.. date: 2019-05-12-12-58-37 +.. nonce: 6xiEHZ +.. section: Library + +Ensure method signature is used instead of constructor signature of a class +while asserting mock object against method calls. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 35070 +.. date: 2019-05-09-18-50-55 +.. nonce: 4vaqNL +.. section: Library + +posix.getgrouplist() now works correctly when the user belongs to +NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 31783 +.. date: 2019-05-07-19-25-55 +.. nonce: lgLo69 +.. section: Library + +Fix race condition in ThreadPoolExecutor when worker threads are created +during interpreter shutdown. + +.. + +.. bpo: 36582 +.. date: 2019-05-07-17-42-36 +.. nonce: L_dxR6 +.. section: Library + +Fix ``UserString.encode()`` to correctly return ``bytes`` rather than a +``UserString`` instance. + +.. + +.. bpo: 32424 +.. date: 2019-04-28-10-34-19 +.. nonce: eqNPhM +.. section: Library + +Deprecate xml.etree.ElementTree.Element.copy() in favor of copy.copy(). + +Patch by Gordon P. Hemsley + +.. + +.. bpo: 36564 +.. date: 2019-04-08-13-00-13 +.. nonce: _n67m_ +.. section: Library + +Fix infinite loop in email header folding logic that would be triggered when +an email policy's max_line_length is not long enough to include the required +markup and any values in the message. Patch by Paul Ganssle + +.. + +.. bpo: 36543 +.. date: 2019-04-06-20-08-12 +.. nonce: RPjmUz +.. section: Library + +Removed methods Element.getchildren(), Element.getiterator() and +ElementTree.getiterator() and the xml.etree.cElementTree module. + +.. + +.. bpo: 36409 +.. date: 2019-03-23-16-42-46 +.. nonce: ZYVKao +.. section: Library + +Remove the old plistlib API deprecated in Python 3.4 + +.. + +.. bpo: 36302 +.. date: 2019-03-21-19-23-46 +.. nonce: Yc591g +.. section: Library + +distutils sorts source file lists so that Extension .so files build more +reproducibly by default + +.. + +.. bpo: 36250 +.. date: 2019-03-09-16-04-12 +.. nonce: tSK4N1 +.. section: Library + +Ignore ``ValueError`` from ``signal`` with ``interaction`` in non-main +thread. + +.. + +.. bpo: 36046 +.. date: 2019-02-19-17-32-45 +.. nonce: fX9OPj +.. section: Library + +Added ``user``, ``group`` and ``extra_groups`` parameters to the +subprocess.Popen constructor. Patch by Patrick McLean. + +.. + +.. bpo: 32627 +.. date: 2019-02-03-19-13-08 +.. nonce: b68f64 +.. section: Library + +Fix compile error when ``_uuid`` headers conflicting included. + +.. + +.. bpo: 35800 +.. date: 2019-01-25-17-12-17 +.. nonce: MCGJdQ +.. section: Library + +Deprecate ``smtpd.MailmanProxy`` ready for future removal. + +.. + +.. bpo: 35168 +.. date: 2019-01-22-09-23-20 +.. nonce: UGv2yW +.. section: Library + +:attr:`shlex.shlex.punctuation_chars` is now a read-only property. + +.. + +.. bpo: 8538 +.. date: 2019-01-09-16-18-52 +.. nonce: PfVZia +.. section: Library + +Add support for boolean actions like ``--foo`` and ``--no-foo`` to argparse. +Patch contributed by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 20504 +.. date: 2018-11-21-18-05-50 +.. nonce: kG0ub5 +.. section: Library + +Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no +`Content-Length` header. + +.. + +.. bpo: 25988 +.. date: 2018-11-19-10-23-58 +.. nonce: 6o7gGK +.. section: Library + +The abstract base classes in :mod:`collections.abc` no longer are exposed in +the regular :mod:`collections` module. + +.. + +.. bpo: 11122 +.. date: 2018-11-12-19-08-50 +.. nonce: Gj7BQn +.. section: Library + +Distutils won't check for rpmbuild in specified paths only. + +.. + +.. bpo: 34775 +.. date: 2018-09-23-03-18-52 +.. nonce: vHeuHk +.. section: Library + +Division handling of PurePath now returns NotImplemented instead of raising +a TypeError when passed something other than an instance of str or PurePath. +Patch by Roger Aiudi. + +.. + +.. bpo: 34749 +.. date: 2018-09-21-13-23-29 +.. nonce: B0k819 +.. section: Library + +:func:`binascii.a2b_base64` is now up to 2 times faster. Patch by Sergey +Fedoseev. + +.. + +.. bpo: 34519 +.. date: 2018-08-27-15-44-50 +.. nonce: cPlH1h +.. section: Library + +Add additional aliases for HP Roman 8. Patch by Michael Osipov. + +.. + +.. bpo: 28009 +.. date: 2018-08-04-12-26-11 +.. nonce: 4JcHZb +.. section: Library + +Fix uuid.getnode() on platforms with '.' as MAC Addr delimiter as well fix +for MAC Addr format that omits a leading 0 in MAC Addr values. Currently, +AIX is the only know platform with these settings. Patch by Michael Felt. + +.. + +.. bpo: 30618 +.. date: 2018-07-14-13-48-56 +.. nonce: T5AUF6 +.. section: Library + +Add :meth:`~pathlib.Path.readlink`. Patch by Girts Folkmanis. + +.. + +.. bpo: 32498 +.. date: 2018-06-17-21-02-25 +.. nonce: La3TZz +.. section: Library + +Made :func:`urllib.parse.unquote()` accept bytes in addition to strings. +Patch by Stein Karlsen. + +.. + +.. bpo: 33348 +.. date: 2018-04-24-13-18-48 +.. nonce: XaJDei +.. section: Library + +lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or +[])``. + +.. + +.. bpo: 32689 +.. date: 2018-02-13-17-58-30 +.. nonce: a-3SnH +.. section: Library + +Update :func:`shutil.move` function to allow for Path objects to be used as +source argument. Patch by Emily Morehouse and Maxwell "5.13b" McKinnon. + +.. + +.. bpo: 32820 +.. date: 2018-02-13-12-25-43 +.. nonce: 0stF0u +.. section: Library + +Added __format__ to IPv4 and IPv6 classes. Always outputs a fully zero- +padded string. Supports b/x/n modifiers (bin/hex/native format). Native +format for IPv4 is bin, native format for IPv6 is hex. Also supports '#' and +'_' modifiers. + +.. + +.. bpo: 27657 +.. date: 2017-12-26-14-32-23 +.. nonce: 6BhyVK +.. section: Library + +Fix urllib.parse.urlparse() with numeric paths. A string like "path:80" is +no longer parsed as a path but as a scheme ("path") and a path ("80"). + +.. + +.. bpo: 4963 +.. date: 2017-08-15-11-24-41 +.. nonce: LRYres +.. section: Library + +Fixed non-deterministic behavior related to mimetypes extension mapping and +module reinitialization. + +.. + +.. bpo: 21767 +.. date: 2019-11-17-11-54-57 +.. nonce: Qq3Dos +.. section: Documentation + +Explicitly mention abc support in functools.singledispatch + +.. + +.. bpo: 38816 +.. date: 2019-11-15-11-39-13 +.. nonce: vUaSVL +.. section: Documentation + +Provides more details about the interaction between :c:func:`fork` and +CPython's runtime, focusing just on the C-API. This includes cautions about +where :c:func:`fork` should and shouldn't be called. + +.. + +.. bpo: 38351 +.. date: 2019-11-15-09-22-28 +.. nonce: xwhlse +.. section: Documentation + +Modernize :mod:`email` examples from %-formatting to f-strings. + +.. + +.. bpo: 38778 +.. date: 2019-11-12-15-31-09 +.. nonce: PHhTlv +.. section: Documentation + +Document the fact that :exc:`RuntimeError` is raised if :meth:`os.fork` is +called in a subinterpreter. + +.. + +.. bpo: 38592 +.. date: 2019-10-26-13-19-07 +.. nonce: Y96BYO +.. section: Documentation + +Add Brazilian Portuguese to the language switcher at Python Documentation +website. + +.. + +.. bpo: 38294 +.. date: 2019-09-27-23-37-41 +.. nonce: go_jFf +.. section: Documentation + +Add list of no-longer-escaped chars to re.escape documentation + +.. + +.. bpo: 38053 +.. date: 2019-09-07-19-09-01 +.. nonce: lttibE +.. section: Documentation + +Modernized the plistlib documentation + +.. + +.. bpo: 26868 +.. date: 2019-09-07-15-55-46 +.. nonce: Raw0Gd +.. section: Documentation + +Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. + +.. + +.. bpo: 36797 +.. date: 2019-09-05-14-47-51 +.. nonce: KN9Ga5 +.. section: Documentation + +Fix a dead link in the distutils API Reference. + +.. + +.. bpo: 37977 +.. date: 2019-08-29-14-38-01 +.. nonce: pML-UI +.. section: Documentation + +Warn more strongly and clearly about pickle insecurity + +.. + +.. bpo: 37979 +.. date: 2019-08-29-10-40-05 +.. nonce: TAUx_E +.. section: Documentation + +Added a link to dateutil.parser.isoparse in the datetime.fromisoformat +documentation. Patch by Paul Ganssle + +.. + +.. bpo: 12707 +.. date: 2019-08-27-01-14-59 +.. nonce: Yj3_7_ +.. section: Documentation + +Deprecate info(), geturl(), getcode() methods in favor of the headers, url, +and status properties, respectively, for HTTPResponse and addinfourl. Also +deprecate the code attribute of addinfourl in favor of the status attribute. +Patch by Ashwin Ramaswami + +.. + +.. bpo: 37937 +.. date: 2019-08-24-12-59-06 +.. nonce: F7fHbt +.. section: Documentation + +Mention ``frame.f_trace`` in :func:`sys.settrace` docs. + +.. + +.. bpo: 37878 +.. date: 2019-08-16-20-01-10 +.. nonce: MvA6rZ +.. section: Documentation + +Make :c:func:`PyThreadState_DeleteCurrent` Internal. + +.. + +.. bpo: 37759 +.. date: 2019-08-04-19-20-58 +.. nonce: EHRF4i +.. section: Documentation + +Beginning edits to Whatsnew 3.8 + +.. + +.. bpo: 37726 +.. date: 2019-07-31-11-40-06 +.. nonce: h-3o9a +.. section: Documentation + +Stop recommending getopt in the tutorial for command line argument parsing +and promote argparse. + +.. + +.. bpo: 32910 +.. date: 2019-07-25-10-30-32 +.. nonce: caLLAe +.. section: Documentation + +Remove implementation-specific behaviour of how venv's Deactivate works. + +.. + +.. bpo: 37256 +.. date: 2019-07-16-14-48-12 +.. nonce: qJTrBb +.. section: Documentation + +Fix wording of arguments for :class:`Request` in :mod:`urllib.request` + +.. + +.. bpo: 37284 +.. date: 2019-07-13-12-58-20 +.. nonce: rP8WpB +.. section: Documentation + +Add a brief note to indicate that any new ``sys.implementation`` required +attributes must go through the PEP process. + +.. + +.. bpo: 30088 +.. date: 2019-07-13-12-43-01 +.. nonce: CIcBjy +.. section: Documentation + +Documented that :class:`mailbox.Maildir` constructor doesn't attempt to +verify the maildir folder layout correctness. Patch by Sviatoslav Sydorenko. + +.. + +.. bpo: 37521 +.. date: 2019-07-12-15-09-56 +.. nonce: 7tiFR- +.. section: Documentation + +Fix `importlib` examples to insert any newly created modules via +importlib.util.module_from_spec() immediately into sys.modules instead of +after calling loader.exec_module(). + +Thanks to Benjamin Mintz for finding the bug. + +.. + +.. bpo: 37456 +.. date: 2019-07-06-17-51-36 +.. nonce: lgAQHn +.. section: Documentation + +Slash ('/') is now part of syntax. + +.. + +.. bpo: 37487 +.. date: 2019-07-06-17-19-26 +.. nonce: QagfZ5 +.. section: Documentation + +Fix PyList_GetItem index description to include 0. + +.. + +.. bpo: 37149 +.. date: 2019-07-06-02-19-02 +.. nonce: NumHn3 +.. section: Documentation + +Replace the dead link to the Tkinter 8.5 reference by John Shipman, New +Mexico Tech, with a link to the archive.org copy. + +.. + +.. bpo: 37478 +.. date: 2019-07-06-00-57-27 +.. nonce: B0ioLw +.. section: Documentation + +Added possible exceptions to the description of os.chdir(). + +.. + +.. bpo: 34903 +.. date: 2019-06-17-09-36-46 +.. nonce: r_wGRc +.. section: Documentation + +Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in +some two-digit formats is optional. Patch by Mike Gleen. + +.. + +.. bpo: 36260 +.. date: 2019-06-04-09-29-00 +.. nonce: WrGuc- +.. section: Documentation + +Add decompression pitfalls to zipfile module documentation. + +.. + +.. bpo: 37004 +.. date: 2019-05-22-04-30-07 +.. nonce: BRgxrt +.. section: Documentation + +In the documentation for difflib, a note was added explicitly warning that +the results of SequenceMatcher's ratio method may depend on the order of the +input strings. + +.. + +.. bpo: 36960 +.. date: 2019-05-18-16-25-44 +.. nonce: xEKHXj +.. section: Documentation + +Restructured the :mod:`datetime` docs in the interest of making them more +user-friendly and improving readability. Patch by Brad Solomon. + +.. + +.. bpo: 36487 +.. date: 2019-04-02-19-23-00 +.. nonce: Jg6-MG +.. section: Documentation + +Make C-API docs clear about what the "main" interpreter is. + +.. + +.. bpo: 23460 +.. date: 2019-02-14-07-12-48 +.. nonce: Iqiqtm +.. section: Documentation + +The documentation for decimal string formatting using the `:g` specifier has +been updated to reflect the correct exponential notation cutoff point. +Original patch contributed by Tuomas Suutari. + +.. + +.. bpo: 35803 +.. date: 2019-01-21-14-30-59 +.. nonce: yae6Lq +.. section: Documentation + +Document and test that ``tempfile`` functions may accept a :term:`path-like +object` for the ``dir`` argument. Patch by Anthony Sottile. + +.. + +.. bpo: 33944 +.. date: 2018-10-26-18-10-29 +.. nonce: V1YeOA +.. section: Documentation + +Added a note about the intended use of code in .pth files. + +.. + +.. bpo: 34293 +.. date: 2018-07-31-15-38-26 +.. nonce: yHupAL +.. section: Documentation + +Fix the Doc/Makefile regarding PAPER environment variable and PDF builds + +.. + +.. bpo: 25237 +.. date: 2018-06-02-12-55-23 +.. nonce: m8-JMu +.. section: Documentation + +Add documentation for tkinter modules + +.. + +.. bpo: 38614 +.. date: 2019-10-30-15-12-32 +.. nonce: M6UnLB +.. section: Tests + +Fix test_communicate() of test_asyncio.test_subprocess: use +``support.LONG_TIMEOUT`` (5 minutes), instead of just 1 minute. + +.. + +.. bpo: 38614 +.. date: 2019-10-28-15-56-02 +.. nonce: aDdDYE +.. section: Tests + +Add timeout constants to :mod:`test.support`: +:data:`~test.support.LOOPBACK_TIMEOUT`, +:data:`~test.support.INTERNET_TIMEOUT`, :data:`~test.support.SHORT_TIMEOUT` +and :data:`~test.support.LONG_TIMEOUT`. + +.. + +.. bpo: 38502 +.. date: 2019-10-17-00-49-38 +.. nonce: vUEic7 +.. section: Tests + +test.regrtest now uses process groups in the multiprocessing mode (-jN +command line option) if process groups are available: if :func:`os.setsid` +and :func:`os.killpg` functions are available. + +.. + +.. bpo: 35998 +.. date: 2019-10-16-01-36-15 +.. nonce: G305Bf +.. section: Tests + +Fix a race condition in test_asyncio.test_start_tls_server_1(). Previously, +there was a race condition between the test main() function which replaces +the protocol and the test ServerProto protocol which sends ANSWER once it +gets HELLO. Now, only the test main() function is responsible to send data, +ServerProto no longer sends data. + +.. + +.. bpo: 38470 +.. date: 2019-10-14-22-46-35 +.. nonce: NHtzpy +.. section: Tests + +Fix ``test_compileall.test_compile_dir_maxlevels()`` on Windows without long +path support: only create 3 subdirectories instead of between 20 and 100 +subdirectories. + +.. + +.. bpo: 37531 +.. date: 2019-10-08-16-42-05 +.. nonce: 7v-_Ca +.. section: Tests + +On timeout, regrtest no longer attempts to call ``popen.communicate()`` +again: it can hang until all child processes using stdout and stderr pipes +completes. Kill the worker process and ignores its output. Change also the +faulthandler timeout of the main process from 1 minute to 5 minutes, for +Python slowest buildbots. + +.. + +.. bpo: 38239 +.. date: 2019-09-26-15-48-36 +.. nonce: MfoVzY +.. section: Tests + +Fix test_gdb for Link Time Optimization (LTO) builds. + +.. + +.. bpo: 38275 +.. date: 2019-09-25-14-40-57 +.. nonce: -kdveI +.. section: Tests + +test_ssl now handles disabled TLS/SSL versions better. OpenSSL's crypto +policy and run-time settings are recognized and tests for disabled versions +are skipped. Tests also accept more TLS minimum_versions for platforms that +override OpenSSL's default with strict settings. + +.. + +.. bpo: 38271 +.. date: 2019-09-25-13-11-29 +.. nonce: iHXNIg +.. section: Tests + +The private keys for test_ssl were encrypted with 3DES in traditional PKCS#5 +format. 3DES and the digest algorithm of PKCS#5 are blocked by some strict +crypto policies. Use PKCS#8 format with AES256 encryption instead. + +.. + +.. bpo: 38270 +.. date: 2019-09-25-12-18-31 +.. nonce: _x-9uH +.. section: Tests + +test.support now has a helper function to check for availibility of a hash +digest function. Several tests are refactored avoid MD5 and use SHA256 +instead. Other tests are marked to use MD5 and skipped when MD5 is disabled. + +.. + +.. bpo: 37123 +.. date: 2019-09-24-12-30-55 +.. nonce: IoutBn +.. section: Tests + +Multiprocessing test test_mymanager() now also expects -SIGTERM, not only +exitcode 0. BaseManager._finalize_manager() sends SIGTERM to the manager +process if it takes longer than 1 second to stop, which happens on slow +buildbots. + +.. + +.. bpo: 38212 +.. date: 2019-09-24-12-24-05 +.. nonce: IWbhWz +.. section: Tests + +Multiprocessing tests: increase test_queue_feeder_donot_stop_onexc() timeout +from 1 to 60 seconds. + +.. + +.. bpo: 38117 +.. date: 2019-09-11-17-22-32 +.. nonce: X7LgGY +.. section: Tests + +Test with OpenSSL 1.1.1d + +.. + +.. bpo: 38018 +.. date: 2019-09-03-19-33-10 +.. nonce: zTrMu7 +.. section: Tests + +Increase code coverage for multiprocessing.shared_memory. + +.. + +.. bpo: 37805 +.. date: 2019-08-25-19-51-46 +.. nonce: Kl1sti +.. section: Tests + +Add tests for json.dump(..., skipkeys=3DTrue). Patch by Dong-hee Na. + +.. + +.. bpo: 37531 +.. date: 2019-08-20-19-24-19 +.. nonce: wRoXfU +.. section: Tests + +Enhance regrtest multiprocess timeout: write a message when killing a worker +process, catch popen.kill() and popen.wait() exceptions, put a timeout on +the second call to popen.communicate(). + +.. + +.. bpo: 37876 +.. date: 2019-08-16-16-15-14 +.. nonce: m3k1w3 +.. section: Tests + +Add tests for ROT-13 codec. + +.. + +.. bpo: 36833 +.. date: 2019-07-18-14-52-58 +.. nonce: Zoe9ek +.. section: Tests + +Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of the +:mod:`datetime` module. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37558 +.. date: 2019-07-11-10-33-56 +.. nonce: SKHRsL +.. section: Tests + +Fix test_shared_memory_cleaned_after_process_termination name handling + +.. + +.. bpo: 37526 +.. date: 2019-07-09-12-33-18 +.. nonce: vmm5y7 +.. section: Tests + +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. + +.. + +.. bpo: 37421 +.. date: 2019-07-08-10-11-36 +.. nonce: OY77go +.. section: Tests + +test_concurrent_futures now explicitly stops the ForkServer instance if it's +running. + +.. + +.. bpo: 37421 +.. date: 2019-07-05-14-47-55 +.. nonce: n8o2to +.. section: Tests + +multiprocessing tests now stop the ForkServer instance if it's running: +close the "alive" file descriptor to ask the server to stop and then remove +its UNIX address. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-00-05-28 +.. nonce: ORGRSG +.. section: Tests + +test_distutils.test_build_ext() is now able to remove the temporary +directory on Windows: don't import the newly built C extension ("xx") in the +current process, but test it in a separated process. + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-29-06 +.. nonce: WEfc5A +.. section: Tests + +test_concurrent_futures now cleans up multiprocessing to remove immediately +temporary directories created by multiprocessing.util.get_temp_dir(). + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-20-35 +.. nonce: HCkKWz +.. section: Tests + +test_winconsoleio doesn't leak a temporary file anymore: use +tempfile.TemporaryFile() to remove it when the test completes. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-57-26 +.. nonce: NFH1f0 +.. section: Tests + +multiprocessing tests now explicitly call ``_run_finalizers()`` to +immediately remove temporary directories created by tests. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-56-17 +.. nonce: bOe350 +.. section: Tests + +urllib.request tests now call :func:`~urllib.request.urlcleanup` to remove +temporary files created by ``urlretrieve()`` tests and to clear the +``_opener`` global variable set by ``urlopen()`` and functions calling +indirectly ``urlopen()``. + +.. + +.. bpo: 37472 +.. date: 2019-07-01-17-19-47 +.. nonce: WzkEAx +.. section: Tests + +Remove ``Lib/test/outstanding_bugs.py``. + +.. + +.. bpo: 37199 +.. date: 2019-06-29-23-56-28 +.. nonce: FHDsLf +.. section: Tests + +Fix test failures when IPv6 is unavailable or disabled. + +.. + +.. bpo: 19696 +.. date: 2019-06-29-16-02-21 +.. nonce: 05ijhN +.. section: Tests + +Replace deprecated method "random.choose" with "random.choice" in +"test_pkg_import.py". + +.. + +.. bpo: 37335 +.. date: 2019-06-28-16-37-52 +.. nonce: o5S2hY +.. section: Tests + +Remove no longer necessary code from c locale coercion tests + +.. + +.. bpo: 37421 +.. date: 2019-06-27-00-37-59 +.. nonce: rVJb3x +.. section: Tests + +Fix test_shutil to no longer leak temporary files. + +.. + +.. bpo: 37411 +.. date: 2019-06-26-15-28-45 +.. nonce: 5lGNhM +.. section: Tests + +Fix test_wsgiref.testEnviron() to no longer depend on the environment +variables (don't fail if "X" variable is set). + +.. + +.. bpo: 37400 +.. date: 2019-06-25-16-02-43 +.. nonce: cx_EWv +.. section: Tests + +Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() to +get groups. Rename also the test to test_chown_gid(). + +.. + +.. bpo: 37359 +.. date: 2019-06-24-10-47-07 +.. nonce: CkdtyO +.. section: Tests + +Add --cleanup option to python3 -m test to remove ``test_python_*`` +directories of previous failed jobs. Add "make cleantest" to run ``python3 +-m test --cleanup``. + +.. + +.. bpo: 37362 +.. date: 2019-06-21-15-47-33 +.. nonce: D3xppx +.. section: Tests + +test_gdb no longer fails if it gets an "unexpected" message on stderr: it +now ignores stderr. The purpose of test_gdb is to test that python-gdb.py +commands work as expected, not to test gdb. + +.. + +.. bpo: 35998 +.. date: 2019-06-14-17-05-49 +.. nonce: yX82oD +.. section: Tests + +Avoid TimeoutError in test_asyncio: test_start_tls_server_1() + +.. + +.. bpo: 37278 +.. date: 2019-06-14-12-21-47 +.. nonce: z0HUOr +.. section: Tests + +Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a +running thread and leaking a reference. + +.. + +.. bpo: 37261 +.. date: 2019-06-13-12-19-56 +.. nonce: NuKFVo +.. section: Tests + +Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method +now ignores unraisable exception raised when clearing its ``unraisable`` +attribute. + +.. + +.. bpo: 37069 +.. date: 2019-06-13-00-46-25 +.. nonce: wdktFo +.. section: Tests + +regrtest now uses :func:`sys.unraisablehook` to mark a test as "environment +altered" (ENV_CHANGED) if it emits an "unraisable exception". Moreover, +regrtest logs a warning in this case. + +Use ``python3 -m test --fail-env-changed`` to catch unraisable exceptions in +tests. + +.. + +.. bpo: 37252 +.. date: 2019-06-12-14-30-29 +.. nonce: 4o-uLs +.. section: Tests + +Fix assertions in ``test_close`` and ``test_events_mask_overflow`` devpoll +tests. + +.. + +.. bpo: 37169 +.. date: 2019-06-07-12-23-15 +.. nonce: yfXTFg +.. section: Tests + +Rewrite ``_PyObject_IsFreed()`` unit tests. + +.. + +.. bpo: 37153 +.. date: 2019-06-04-18-30-39 +.. nonce: 711INB +.. section: Tests + +``test_venv.test_multiprocessing()`` now explicitly calls +``pool.terminate()`` to wait until the pool completes. + +.. + +.. bpo: 34001 +.. date: 2019-06-03-20-47-10 +.. nonce: KvYx9z +.. section: Tests + +Make test_ssl pass with LibreSSL. LibreSSL handles minimum and maximum TLS +version differently than OpenSSL. + +.. + +.. bpo: 36919 +.. date: 2019-05-28-15-41-34 +.. nonce: -vGt_m +.. section: Tests + +Make ``test_source_encoding.test_issue2301`` implementation independent. The +test will work now for both CPython and IronPython. + +.. + +.. bpo: 30202 +.. date: 2019-04-15-19-05-35 +.. nonce: Wt7INj +.. section: Tests + +Update ``test.test_importlib.test_abc`` to test ``find_spec()``. + +.. + +.. bpo: 28009 +.. date: 2019-04-11-07-59-43 +.. nonce: s85urF +.. section: Tests + +Modify the test_uuid logic to test when a program is available AND can be +used to obtain a MACADDR as basis for an UUID. Patch by M. Felt + +.. + +.. bpo: 34596 +.. date: 2018-09-07-01-18-27 +.. nonce: r2-EGd +.. section: Tests + +Fallback to a default reason when :func:`unittest.skip` is uncalled. Patch +by Naitree Zhu. + +.. + +.. bpo: 38809 +.. date: 2019-11-15-09-25-44 +.. nonce: 9jwta6 +.. section: Build + +On Windows, build scripts will now recognize and use python.exe from an +active virtual env. + +.. + +.. bpo: 38684 +.. date: 2019-11-04-14-30-37 +.. nonce: aed593 +.. section: Build + +Fix _hashlib build when Blake2 is disabled, but OpenSSL supports it. + +.. + +.. bpo: 38468 +.. date: 2019-10-13-16-18-24 +.. nonce: buCO84 +.. section: Build + +Misc/python-config.in now uses `getvar()` for all still existing +`sysconfig.get_config_var()` calls. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37415 +.. date: 2019-10-11-15-32-58 +.. nonce: D9RXrq +.. section: Build + +Fix stdatomic.h header check for ICC compiler: the ICC implementation lacks +atomic_uintptr_t type which is needed by Python. + +.. + +.. bpo: 38301 +.. date: 2019-09-28-02-37-11 +.. nonce: 123456 +.. section: Build + +In Solaris family, we must be sure to use ``-D_REENTRANT``. Patch by Jes=C3= =BAs +Cea Avi=C3=B3n. + +.. + +.. bpo: 36002 +.. date: 2019-09-13-14-12-36 +.. nonce: Bcl4oe +.. section: Build + +Locate ``llvm-profdata`` and ``llvm-ar`` binaries using ``AC_PATH_TOOL`` +rather than ``AC_PATH_TARGET_TOOL``. + +.. + +.. bpo: 37936 +.. date: 2019-09-10-00-54-48 +.. nonce: E7XEwu +.. section: Build + +The :file:`.gitignore` file systematically keeps "rooted", with a +non-trailing slash, all the rules that are meant to apply to files in a +specific place in the repo. Previously, when the intended file to ignore +happened to be at the root of the repo, we'd most often accidentally also +ignore files and directories with the same name anywhere in the tree. + +.. + +.. bpo: 37760 +.. date: 2019-08-24-17-39-09 +.. nonce: f3jXuH +.. section: Build + +The :file:`Tools/unicode/makeunicodedata.py` script, which is used for +converting information from the Unicode Character Database into generated +code and data used by the methods of :class:`str` and by the +:mod:`unicodedata` module, now handles each character's data as a +``dataclass`` with named attributes, rather than a length-18 list of +different fields. + +.. + +.. bpo: 37936 +.. date: 2019-08-24-00-29-40 +.. nonce: QrORqA +.. section: Build + +The :file:`.gitignore` file no longer applies to any files that are in fact +tracked in the Git repository. Patch by Greg Price. + +.. + +.. bpo: 37725 +.. date: 2019-07-30-16-26-11 +.. nonce: MkG1TT +.. section: Build + +Change "clean" makefile target to also clean the program guided optimization +(PGO) data. Previously you would have to use "make clean" and "make +profile-removal", or "make clobber". + +.. + +.. bpo: 37707 +.. date: 2019-07-29-11-36-16 +.. nonce: Sm-dGk +.. section: Build + +Mark some individual tests to skip when --pgo is used. The tests marked +increase the PGO task time significantly and likely don't help improve +optimization of the final executable. + +.. + +.. bpo: 36044 +.. date: 2019-07-11-01-28-24 +.. nonce: gIgfiJ +.. section: Build + +Reduce the number of unit tests run for the PGO generation task. This +speeds up the task by a factor of about 15x. Running the full unit test +suite is slow. This change may result in a slightly less optimized build +since not as many code branches will be executed. If you are willing to +wait for the much slower build, the old behavior can be restored using +'./configure [..] PROFILE_TASK=3D"-m test --pgo-extended"'. We make no +guarantees as to which PGO task set produces a faster build. Users who care +should run their own relevant benchmarks as results can depend on the +environment, workload, and compiler tool chain. + +.. + +.. bpo: 37468 +.. date: 2019-07-01-14-39-40 +.. nonce: trbQ-_ +.. section: Build + +``make install`` no longer installs ``wininst-*.exe`` files used by +distutils bdist_wininst: bdist_wininst only works on Windows. + +.. + +.. bpo: 37189 +.. date: 2019-06-17-09-40-59 +.. nonce: j5ebdT +.. section: Build + +Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer +exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI +compatibility. + +.. + +.. bpo: 25361 +.. date: 2019-03-19-22-07-37 +.. nonce: XO9Bfr +.. section: Build + +Enables use of SSE2 instructions in Windows 32-bit build. + +.. + +.. bpo: 36210 +.. date: 2019-03-06-18-55-10 +.. nonce: fup9H2 +.. section: Build + +Update optional extension module detection for AIX. ossaudiodev and spwd are +not applicable for AIX, and are no longer reported as missing. 3rd-party +packaging of ncurses (with ASIS support) conflicts with officially supported +AIX curses library, so configure AIX to use libcurses.a. However, skip +trying to build _curses_panel. + +patch by M Felt + +.. + +.. bpo: 38589 +.. date: 2019-10-28-10-48-16 +.. nonce: V69Q1a +.. section: Windows + +Fixes HTML Help shortcut when Windows is not installed to C drive + +.. + +.. bpo: 38453 +.. date: 2019-10-28-10-32-43 +.. nonce: NwwatW +.. section: Windows + +Ensure ntpath.realpath() correctly resolves relative paths. + +.. + +.. bpo: 38519 +.. date: 2019-10-28-05-01-29 +.. nonce: dCkY66 +.. section: Windows + +Restores the internal C headers that were missing from the nuget.org and +Microsoft Store packages. + +.. + +.. bpo: 38492 +.. date: 2019-10-16-09-49-09 +.. nonce: Te1LxC +.. section: Windows + +Remove ``pythonw.exe`` dependency on the Microsoft C++ runtime. + +.. + +.. bpo: 38344 +.. date: 2019-10-05-05-50-58 +.. nonce: scr2LO +.. section: Windows + +Fix error message in activate.bat + +.. + +.. bpo: 38359 +.. date: 2019-10-03-08-04-14 +.. nonce: wzwsl_ +.. section: Windows + +Ensures ``pyw.exe`` launcher reads correct registry key. + +.. + +.. bpo: 38355 +.. date: 2019-10-02-15-38-49 +.. nonce: n3AWX6 +.. section: Windows + +Fixes ``ntpath.realpath`` failing on ``sys.executable``. + +.. + +.. bpo: 38117 +.. date: 2019-09-16-14-07-11 +.. nonce: hJVf0C +.. section: Windows + +Update bundled OpenSSL to 1.1.1d + +.. + +.. bpo: 38092 +.. date: 2019-09-13-14-11-42 +.. nonce: x31ehI +.. section: Windows + +Reduce overhead when using multiprocessing in a Windows virtual environment. + +.. + +.. bpo: 38133 +.. date: 2019-09-12-12-05-55 +.. nonce: yFeRGS +.. section: Windows + +Allow py.exe launcher to locate installations from the Microsoft Store and +improve display of active virtual environments. + +.. + +.. bpo: 38114 +.. date: 2019-09-11-15-24-04 +.. nonce: cc0E5E +.. section: Windows + +The ``pip.ini`` is no longer included in the Nuget package. + +.. + +.. bpo: 32592 +.. date: 2019-09-11-14-51-56 +.. nonce: jvQMD9 +.. section: Windows + +Set Windows 8 as the minimum required version for API support + +.. + +.. bpo: 36634 +.. date: 2019-09-11-14-42-04 +.. nonce: 8Un8ih +.. section: Windows + +:func:`os.cpu_count` now returns active processors rather than maximum +processors. + +.. + +.. bpo: 36634 +.. date: 2019-09-11-12-34-31 +.. nonce: xLaGgb +.. section: Windows + +venv activate.bat now works when the existing variables contain double quote +characters. + +.. + +.. bpo: 38081 +.. date: 2019-09-11-10-22-01 +.. nonce: 8JhzjD +.. section: Windows + +Prevent error calling :func:`os.path.realpath` on ``'NUL'``. + +.. + +.. bpo: 38087 +.. date: 2019-09-10-14-21-40 +.. nonce: --eIib +.. section: Windows + +Fix case sensitivity in test_pathlib and test_ntpath. + +.. + +.. bpo: 38088 +.. date: 2019-09-10-14-17-25 +.. nonce: FOvWSM +.. section: Windows + +Fixes distutils not finding vcruntime140.dll with only the v142 toolset +installed. + +.. + +.. bpo: 37283 +.. date: 2019-09-09-12-22-23 +.. nonce: 8NvOkU +.. section: Windows + +Ensure command-line and unattend.xml setting override previously detected +states in Windows installer. + +.. + +.. bpo: 38030 +.. date: 2019-09-04-14-01-08 +.. nonce: _USdtk +.. section: Windows + +Fixes :func:`os.stat` failing for block devices on Windows + +.. + +.. bpo: 38020 +.. date: 2019-09-03-11-47-37 +.. nonce: xFZ2j0 +.. section: Windows + +Fixes potential crash when calling :func:`os.readlink` (or indirectly +through :func:`~os.path.realpath`) on a file that is not a supported link. + +.. + +.. bpo: 37705 +.. date: 2019-08-30-15-15-22 +.. nonce: 2o4NWW +.. section: Windows + +Improve the implementation of ``winerror_to_errno()``. + +.. + +.. bpo: 37549 +.. date: 2019-08-22-09-04-44 +.. nonce: TpKI3M +.. section: Windows + +:func:`os.dup` no longer fails for standard streams on Windows 7. + +.. + +.. bpo: 1311 +.. date: 2019-08-21-12-58-18 +.. nonce: BoW1wU +.. section: Windows + +The ``nul`` file on Windows now returns True from :func:`~os.path.exists` +and a valid result from :func:`os.stat` with ``S_IFCHR`` set. + +.. + +.. bpo: 9949 +.. date: 2019-08-14-13-40-15 +.. nonce: zW45Ks +.. section: Windows + +Enable support for following symlinks in :func:`os.realpath`. + +.. + +.. bpo: 37834 +.. date: 2019-08-12-12-00-24 +.. nonce: VB2QVj +.. section: Windows + +Treat all name surrogate reparse points on Windows in :func:`os.lstat` and +other reparse points as regular files in :func:`os.stat`. + +.. + +.. bpo: 36266 +.. date: 2019-08-08-18-05-27 +.. nonce: x4eZU3 +.. section: Windows + +Add the module name in the formatted error message when DLL load fail +happens during module import in ``_PyImport_FindSharedFuncptrWindows()``. +Patch by Srinivas Nyayapati. + +.. + +.. bpo: 25172 +.. date: 2019-08-06-18-09-18 +.. nonce: Akreij +.. section: Windows + +Trying to import the :mod:`crypt` module on Windows will result in an +:exc:`ImportError` with a message explaining that the module isn't supported +on Windows. On other platforms, if the underlying ``_crypt`` module is not +available, the ImportError will include a message explaining the problem. + +.. + +.. bpo: 37778 +.. date: 2019-08-06-13-54-12 +.. nonce: AY1XhH +.. section: Windows + +Fixes the icons used for file associations to the Microsoft Store package. + +.. + +.. bpo: 37734 +.. date: 2019-08-06-09-35-12 +.. nonce: EoJ9Nh +.. section: Windows + +Fix use of registry values to launch Python from Microsoft Store app. + +.. + +.. bpo: 37702 +.. date: 2019-07-29-16-49-31 +.. nonce: Lj2f5e +.. section: Windows + +Fix memory leak on Windows in creating an SSLContext object or running +urllib.request.urlopen('https://...'). + +.. + +.. bpo: 37672 +.. date: 2019-07-24-14-36-28 +.. nonce: uKEVHN +.. section: Windows + +Switch Windows Store package's pip to use bundled :file:`pip.ini` instead of +:envvar:`PIP_USER` variable. + +.. + +.. bpo: 10945 +.. date: 2019-07-01-12-38-48 +.. nonce: s0YBHG +.. section: Windows + +Officially drop support for creating bdist_wininst installers on non-Windows +systems. + +.. + +.. bpo: 37445 +.. date: 2019-06-28-18-10-29 +.. nonce: LsdYO6 +.. section: Windows + +Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in ``FormatMessageW()`` +calls. + +.. + +.. bpo: 37369 +.. date: 2019-06-28-09-44-08 +.. nonce: 1iVpxq +.. section: Windows + +Fixes path for :data:`sys.executable` when running from the Microsoft Store. + +.. + +.. bpo: 37380 +.. date: 2019-06-25-04-15-22 +.. nonce: tPxjuz +.. section: Windows + +Don't collect unfinished processes with ``subprocess._active`` on Windows to +cleanup later. Patch by Ruslan Kuprieiev. + +.. + +.. bpo: 37351 +.. date: 2019-06-20-12-50-32 +.. nonce: asTnVW +.. section: Windows + +Removes libpython38.a from standard Windows distribution. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-09-05-08 +.. nonce: tdqSmo +.. section: Windows + +Update Windows builds to use SQLite 3.28.0. + +.. + +.. bpo: 37267 +.. date: 2019-06-13-04-15-51 +.. nonce: Ygo5ef +.. section: Windows + +On Windows, :func:`os.dup` no longer creates an inheritable fd when handling +a character file. + +.. + +.. bpo: 36779 +.. date: 2019-06-11-15-41-34 +.. nonce: 0TMw6f +.. section: Windows + +Ensure ``time.tzname`` is correct on Windows when the active code page is +set to CP_UTF7 or CP_UTF8. + +.. + +.. bpo: 32587 +.. date: 2019-05-10-15-25-44 +.. nonce: -0g2O3 +.. section: Windows + +Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. + +.. + +.. bpo: 28269 +.. date: 2019-05-05-05-23-34 +.. nonce: -MOHI7 +.. section: Windows + +Replace use of :c:func:`strcasecmp` for the system function +:c:func:`_stricmp`. Patch by Minmin Gong. + +.. + +.. bpo: 36590 +.. date: 2019-04-10-21-13-26 +.. nonce: ZTaKcu +.. section: Windows + +Add native Bluetooth RFCOMM support to socket module. + +.. + +.. bpo: 38117 +.. date: 2019-09-15-21-29-13 +.. nonce: ZLsoAZ +.. section: macOS + +Updated OpenSSL to 1.1.1d in macOS installer. + +.. + +.. bpo: 38089 +.. date: 2019-09-10-14-24-35 +.. nonce: eedgyD +.. section: macOS + +Move Azure Pipelines to latest VM versions and make macOS tests optional + +.. + +.. bpo: 18049 +.. date: 2019-07-13-15-58-18 +.. nonce: MklhQQ +.. section: macOS + +Increase the default stack size of threads from 5MB to 16MB on macOS, to +match the stack size of the main thread. This avoids crashes on deep +recursion in threads. + +.. + +.. bpo: 34602 +.. date: 2019-07-02-01-06-47 +.. nonce: 10d4wl +.. section: macOS + +Avoid test suite failures on macOS by no longer calling resource.setrlimit +to increase the process stack size limit at runtime. The runtime change is +no longer needed since the interpreter is being built with a larger default +stack size. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-08-58-30 +.. nonce: -CWbfy +.. section: macOS + +Update macOS installer to use SQLite 3.28.0. + +.. + +.. bpo: 34631 +.. date: 2019-06-18-00-30-40 +.. nonce: vSifcv +.. section: macOS + +Updated OpenSSL to 1.1.1c in macOS installer. + +.. + +.. bpo: 26353 +.. date: 2019-11-09-23-55-59 +.. nonce: duYZiF +.. section: IDLE + +Stop adding newline when saving an IDLE shell window. + +.. + +.. bpo: 4630 +.. date: 2019-10-28-04-48-03 +.. nonce: upgjiV +.. section: IDLE + +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. Patch by +Zachary Spytz. + +.. + +.. bpo: 38598 +.. date: 2019-10-26-18-16-24 +.. nonce: 6kH9FY +.. section: IDLE + +Do not try to compile IDLE shell or output windows + +.. + +.. bpo: 36698 +.. date: 2019-10-04-18-03-09 +.. nonce: BKcmom +.. section: IDLE + +IDLE no longer fails when write non-encodable characters to stderr. It now +escapes them with a backslash, as the regular Python interpreter. Added the +``errors`` field to the standard streams. + +.. + +.. bpo: 35379 +.. date: 2019-09-17-01-28-56 +.. nonce: yAECDr +.. section: IDLE + +When exiting IDLE, catch any AttributeError. One happens when +EditorWindow.close is called twice. Printing a traceback, when IDLE is run +from a terminal, is useless and annoying. + +.. + +.. bpo: 38183 +.. date: 2019-09-16-15-04-29 +.. nonce: eudCN1 +.. section: IDLE + +To avoid problems, test_idle ignores the user config directory. It no longer +tries to create or access .idlerc or any files within. Users must run IDLE +to discover problems with saving settings. + +.. + +.. bpo: 38077 +.. date: 2019-09-09-22-08-36 +.. nonce: Mzpfe2 +.. section: IDLE + +IDLE no longer adds 'argv' to the user namespace when initializing it. This +bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. + +.. + +.. bpo: 38041 +.. date: 2019-09-05-23-12-13 +.. nonce: nxmGGK +.. section: IDLE + +Shell restart lines now fill the window width, always start with '=3D', and +avoid wrapping unnecessarily. The line will still wrap if the included file +name is long relative to the width. + +.. + +.. bpo: 35771 +.. date: 2019-09-01-10-22-55 +.. nonce: tdbmbP +.. section: IDLE + +To avoid occasional spurious test_idle failures on slower machines, increase +the ``hover_delay`` in test_tooltip. + +.. + +.. bpo: 37824 +.. date: 2019-08-26-00-41-53 +.. nonce: YY5jAI +.. section: IDLE + +Properly handle user input warnings in IDLE shell. Cease turning +SyntaxWarnings into SyntaxErrors. + +.. + +.. bpo: 37929 +.. date: 2019-08-24-22-00-33 +.. nonce: jb7523 +.. section: IDLE + +IDLE Settings dialog now closes properly when there is no shell window. + +.. + +.. bpo: 37902 +.. date: 2019-08-21-16-02-49 +.. nonce: _R_adE +.. section: IDLE + +Add mousewheel scrolling for IDLE module, path, and stack browsers. Patch by +George Zhang. + +.. + +.. bpo: 37849 +.. date: 2019-08-14-09-43-15 +.. nonce: -bcYF3 +.. section: IDLE + +Fixed completions list appearing too high or low when shown above the +current line. + +.. + +.. bpo: 36419 +.. date: 2019-08-04-17-10-01 +.. nonce: TJZqOc +.. section: IDLE + +Refactor IDLE autocomplete and improve testing. + +.. + +.. bpo: 37748 +.. date: 2019-08-04-15-27-50 +.. nonce: 0vf6pg +.. section: IDLE + +Reorder the Run menu. Put the most common choice, Run Module, at the top. + +.. + +.. bpo: 37692 +.. date: 2019-07-27-15-14-20 +.. nonce: TRHGjD +.. section: IDLE + +Improve highlight config sample with example shell interaction and better +labels for shell elements. + +.. + +.. bpo: 37628 +.. date: 2019-07-26-17-51-13 +.. nonce: kX4AUF +.. section: IDLE + +Settings dialog no longer expands with font size. + +.. + +.. bpo: 37627 +.. date: 2019-07-20-23-33-53 +.. nonce: dQhUNB +.. section: IDLE + +Initialize the Customize Run dialog with the command line arguments most +recently entered before. The user can optionally edit before submitting +them. + +.. + +.. bpo: 33610 +.. date: 2019-07-18-10-11-36 +.. nonce: xYqMLg +.. section: IDLE + +Fix code context not showing the correct context when first toggled on. + +.. + +.. bpo: 37530 +.. date: 2019-07-11-00-05-31 +.. nonce: AuyCyD +.. section: IDLE + +Optimize code context to reduce unneeded background activity. Font and +highlight changes now occur along with text changes instead of after a +random delay. + +.. + +.. bpo: 27452 +.. date: 2019-07-03-22-47-44 +.. nonce: nePPLi +.. section: IDLE + +Cleanup ``config.py`` by inlining ``RemoveFile`` and simplifying the +handling of ``file`` in ``CreateConfigHandlers``. + +.. + +.. bpo: 37325 +.. date: 2019-06-18-16-40-05 +.. nonce: GssOf1 +.. section: IDLE + +Fix tab focus traversal order for help source and custom run dialogs. + +.. + +.. bpo: 37321 +.. date: 2019-06-17-16-35-30 +.. nonce: zVTTGS +.. section: IDLE + +Both subprocess connection error messages now refer to the 'Startup failure' +section of the IDLE doc. + +.. + +.. bpo: 17535 +.. date: 2019-06-13-01-07-20 +.. nonce: K8i2St +.. section: IDLE + +Add optional line numbers for IDLE editor windows. Windows open without +line numbers unless set otherwise in the General tab of the configuration +dialog. + +.. + +.. bpo: 26806 +.. date: 2019-06-10-22-48-50 +.. nonce: Zltkum +.. section: IDLE + +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. + +.. + +.. bpo: 37177 +.. date: 2019-06-07-00-17-41 +.. nonce: voU6pQ +.. section: IDLE + +Properly 'attach' search dialogs to their main window so that they behave +like other dialogs and do not get hidden behind their main window. + +.. + +.. bpo: 37039 +.. date: 2019-06-04-23-27-33 +.. nonce: FN_fBf +.. section: IDLE + +Adjust "Zoom Height" to individual screens by momentarily maximizing the +window on first use with a particular screen. Changing screen settings may +invalidate the saved height. While a window is maximized, "Zoom Height" has +no effect. + +.. + +.. bpo: 35763 +.. date: 2019-06-04-20-36-24 +.. nonce: 7XdoWz +.. section: IDLE + +Make calltip reminder about '/' meaning positional-only less obtrusive by +only adding it when there is room on the first line. + +.. + +.. bpo: 5680 +.. date: 2019-06-03-00-39-29 +.. nonce: VCQfOO +.. section: IDLE + +Add 'Run... Customized' to the Run menu to run a module with customized +settings. Any 'command line arguments' entered are added to sys.argv. One +can suppress the normal Shell main module restart. + +.. + +.. bpo: 36390 +.. date: 2019-03-21-08-35-00 +.. nonce: OdDCGk +.. section: IDLE + +Gather Format menu functions into format.py. Combine paragraph.py, +rstrip.py, and format methods from editor.py. + +.. + +.. bpo: 38118 +.. date: 2019-10-08-15-07-52 +.. nonce: pIZD6H +.. section: Tools/Demos + +Update Valgrind suppression file to ignore a false alarm in +:c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). + +.. + +.. bpo: 38347 +.. date: 2019-10-02-09-48-42 +.. nonce: 2Tq5D1 +.. section: Tools/Demos + +pathfix.py: Assume all files that end on '.py' are Python scripts when +working recursively. + +.. + +.. bpo: 37803 +.. date: 2019-09-12-16-15-55 +.. nonce: chEizy +.. section: Tools/Demos + +pdb's ``--help`` and ``--version`` long options now work. + +.. + +.. bpo: 37942 +.. date: 2019-08-24-12-11-30 +.. nonce: 7H8N9a +.. section: Tools/Demos + +Improve ArgumentClinic converter for floats. + +.. + +.. bpo: 37704 +.. date: 2019-07-29-13-59-19 +.. nonce: xxGUz_ +.. section: Tools/Demos + +Remove ``Tools/scripts/h2py.py``: use cffi to access a C API in Python. + +.. + +.. bpo: 37675 +.. date: 2019-07-24-16-20-54 +.. nonce: 951Cvf +.. section: Tools/Demos + +2to3 now works when run from a zipped standard library. + +.. + +.. bpo: 37034 +.. date: 2019-05-27-16-13-08 +.. nonce: zbTgy8 +.. section: Tools/Demos + +Argument Clinic now uses the argument name on errors with keyword-only +argument instead of their position. Patch contributed by R=C3=A9mi Lapeyre. + +.. + +.. bpo: 37064 +.. date: 2019-05-27-15-26-12 +.. nonce: k_SPW2 +.. section: Tools/Demos + +Add option -k to pathscript.py script: preserve shebang flags. Add option -a +to pathscript.py script: add flags. + +.. + +.. bpo: 37633 +.. date: 2019-11-04-21-10-47 +.. nonce: oOGVdo +.. section: C API + +Re=C3=ABxport some function compatibility wrappers for macros in ``pythonrun= .h``. + +.. + +.. bpo: 38644 +.. date: 2019-11-04-17-59-46 +.. nonce: euO_RR +.. section: C API + +Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` +as regular functions for the limited API. Previously, there were defined as +macros, but these macros didn't work with the limited API which cannot +access ``PyThreadState.recursion_depth`` field. Remove +``_Py_CheckRecursionLimit`` from the stable ABI. + +.. + +.. bpo: 38650 +.. date: 2019-10-30-22-03-03 +.. nonce: 0pi8zt +.. section: C API + +The global variable :c:data:`PyStructSequence_UnnamedField` is now a +constant and refers to a constant string. + +.. + +.. bpo: 38540 +.. date: 2019-10-21-09-24-03 +.. nonce: 314N_T +.. section: C API + +Fixed possible leak in :c:func:`PyArg_Parse` and similar functions for +format units ``"es#"`` and ``"et#"`` when the macro +:c:macro:`PY_SSIZE_T_CLEAN` is not defined. + +.. + +.. bpo: 38395 +.. date: 2019-10-08-01-23-24 +.. nonce: MJ6Ey9 +.. section: C API + +Fix a crash in :class:`weakref.proxy` objects due to incorrect lifetime +management when calling some associated methods that may delete the last +reference to object being referenced by the proxy. Patch by Pablo Galindo. + +.. + +.. bpo: 36389 +.. date: 2019-10-07-17-15-09 +.. nonce: hFX_jD +.. section: C API + +The ``_PyObject_CheckConsistency()`` function is now also available in +release mode. For example, it can be used to debug a crash in the +``visit_decref()`` function of the GC. + +.. + +.. bpo: 38266 +.. date: 2019-10-03-12-53-53 +.. nonce: 0FIC1q +.. section: C API + +Revert the removal of PyThreadState_DeleteCurrent() with documentation. + +.. + +.. bpo: 38303 +.. date: 2019-09-30-16-53-30 +.. nonce: YoIs0M +.. section: C API + +Update audioop extension module to use the stable ABI (PEP-384). Patch by +Tyler Kieft. + +.. + +.. bpo: 38234 +.. date: 2019-09-24-17-09-48 +.. nonce: d0bhEA +.. section: C API + +:c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full +path (:c:func:`Py_GetProgramFullPath`) rather than to the program name +(:c:func:`Py_GetProgramName`). + +.. + +.. bpo: 38234 +.. date: 2019-09-20-17-22-41 +.. nonce: ZbquVK +.. section: C API + +Python ignored arguments passed to :c:func:`Py_SetPath`, +:c:func:`Py_SetPythonHome` and :c:func:`Py_SetProgramName`: fix Python +initialization to use specified arguments. + +.. + +.. bpo: 38205 +.. date: 2019-09-19-18-26-29 +.. nonce: Db1OJL +.. section: C API + +The :c:func:`Py_UNREACHABLE` macro now calls :c:func:`Py_FatalError`. + +.. + +.. bpo: 38140 +.. date: 2019-09-13-01-24-47 +.. nonce: y59qaO +.. section: C API + +Make dict and weakref offsets opaque for C heap types by passing the offsets +through PyMemberDef + +.. + +.. bpo: 15088 +.. date: 2019-09-05-14-17-21 +.. nonce: plt8Em +.. section: C API + +The C function ``PyGen_NeedsFinalizing`` has been removed. It was not +documented, tested or used anywhere within CPython after the implementation +of :pep:`442`. Patch by Joannah Nanjekye. (Patch by Joannah Nanjekye) + +.. + +.. bpo: 36763 +.. date: 2019-08-23-18-45-11 +.. nonce: q3Kh8Z +.. section: C API + +Options added by ``PySys_AddXOption()`` are now handled the same way than +``PyConfig.xoptions`` and command line ``-X`` options. + +.. + +.. bpo: 37926 +.. date: 2019-08-23-11-35-55 +.. nonce: hnI5IQ +.. section: C API + +Fix a crash in ``PySys_SetArgvEx(0, NULL, 0)``. + +.. + +.. bpo: 37879 +.. date: 2019-08-17-13-50-21 +.. nonce: CZeUem +.. section: C API + +Fix subtype_dealloc to suppress the type decref when the base type is a C +heap type + +.. + +.. bpo: 37645 +.. date: 2019-07-21-21-08-47 +.. nonce: 4DcUaI +.. section: C API + +Add :c:func:`_PyObject_FunctionStr` to get a user-friendly string +representation of a function-like object. Patch by Jeroen Demeyer. + +.. + +.. bpo: 29548 +.. date: 2019-07-17-09-50-50 +.. nonce: 5wIptQ +.. section: C API + +The functions ``PyEval_CallObject``, ``PyEval_CallFunction``, +``PyEval_CallMethod`` and ``PyEval_CallObjectWithKeywords`` are deprecated. +Use :c:func:`PyObject_Call` and its variants instead. + +.. + +.. bpo: 37151 +.. date: 2019-07-16-11-02-00 +.. nonce: YKfuNA +.. section: C API + +``PyCFunction_Call`` is now a deprecated alias of :c:func:`PyObject_Call`. + +.. + +.. bpo: 37540 +.. date: 2019-07-10-12-27-28 +.. nonce: E8Z773 +.. section: C API + +The vectorcall protocol now requires that the caller passes only strings as +keyword names. + +.. + +.. bpo: 37207 +.. date: 2019-07-07-10-37-07 +.. nonce: SlVNky +.. section: C API + +The vectorcall protocol is now enabled for ``type`` objects: set +``tp_vectorcall`` to a vectorcall function to be used instead of ``tp_new`` +and ``tp_init`` when calling the class itself. + +.. + +.. bpo: 21120 +.. date: 2019-07-06-23-56-47 +.. nonce: lXHqlT +.. section: C API + +Exclude Python-ast.h, ast.h and asdl.h from the limited API. + +.. + +.. bpo: 37483 +.. date: 2019-07-02-15-42-37 +.. nonce: vftT4f +.. section: C API + +Add new function ``_PyObject_CallOneArg`` for calling an object with one +positional argument. + +.. + +.. bpo: 36763 +.. date: 2019-06-28-15-49-16 +.. nonce: zrmgki +.. section: C API + +Add :func:`PyConfig_SetWideStringList` function. + +.. + +.. bpo: 37337 +.. date: 2019-06-19-12-06-31 +.. nonce: gXIGyU +.. section: C API + +Add fast functions for calling methods: +:c:func:`_PyObject_VectorcallMethod`, :c:func:`_PyObject_CallMethodNoArgs` +and :c:func:`_PyObject_CallMethodOneArg`. + +.. + +.. bpo: 28805 +.. date: 2019-06-14-14-03-51 +.. nonce: qZC0N_ +.. section: C API + +The :const:`METH_FASTCALL` calling convention has been documented. + +.. + +.. bpo: 37221 +.. date: 2019-06-11-02-50-38 +.. nonce: 4tClQT +.. section: C API + +The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create code +objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount* +parameter for indicating the number of positonal-only arguments. + +.. + +.. bpo: 37215 +.. date: 2019-06-10-15-32-34 +.. nonce: yzoNyU +.. section: C API + +Fix dtrace issue introduce by bpo-36842 + +.. + +.. bpo: 37194 +.. date: 2019-06-07-14-03-52 +.. nonce: uck7MD +.. section: C API + +Add a new public :c:func:`PyObject_CallNoArgs` function to the C API: call a +callable Python object without any arguments. It is the most efficient way +to call a callback without any argument. On x86-64, for example, +``PyObject_CallFunctionObjArgs(func, NULL)`` allocates 960 bytes on the +stack per call, whereas ``PyObject_CallNoArgs(func)`` only allocates 624 +bytes per call. + +.. + +.. bpo: 37170 +.. date: 2019-06-06-08-47-04 +.. nonce: hO_fpM +.. section: C API + +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. + +.. + +.. bpo: 35381 +.. date: 2019-01-18-17-05-26 +.. nonce: 9CbeW3 +.. section: C API + +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. + +.. + +.. bpo: 34331 +.. date: 2018-08-04-00-59-44 +.. nonce: iaUkmU +.. section: C API + +Use singular/plural noun in error message when instantiating an abstract +class with non-overriden abstract method(s). diff --git a/Misc/NEWS.d/next/Build/2019-03-06-18-55-10.bpo-36210.fup9H2.rst = b/Misc/NEWS.d/next/Build/2019-03-06-18-55-10.bpo-36210.fup9H2.rst deleted file mode 100644 index aa9a56fe57aec..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-03-06-18-55-10.bpo-36210.fup9H2.rst +++ /dev/null @@ -1,9 +0,0 @@ -Update optional extension module detection for AIX. -ossaudiodev and spwd are not applicable for AIX, and -are no longer reported as missing. -3rd-party packaging of ncurses (with ASIS support) -conflicts with officially supported AIX curses library, -so configure AIX to use libcurses.a. However, skip -trying to build _curses_panel. - -patch by M Felt diff --git a/Misc/NEWS.d/next/Build/2019-03-19-22-07-37.bpo-25361.XO9Bfr.rst = b/Misc/NEWS.d/next/Build/2019-03-19-22-07-37.bpo-25361.XO9Bfr.rst deleted file mode 100644 index 9953b0760faab..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-03-19-22-07-37.bpo-25361.XO9Bfr.rst +++ /dev/null @@ -1 +0,0 @@ -Enables use of SSE2 instructions in Windows 32-bit build. diff --git a/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst = b/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst deleted file mode 100644 index 8b3be5eca72d4..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-06-17-09-40-59.bpo-37189.j5ebdT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were no longer -exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI -compatibility. diff --git a/Misc/NEWS.d/next/Build/2019-07-01-14-39-40.bpo-37468.trbQ-_.rst = b/Misc/NEWS.d/next/Build/2019-07-01-14-39-40.bpo-37468.trbQ-_.rst deleted file mode 100644 index b8c70d574076c..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-07-01-14-39-40.bpo-37468.trbQ-_.rst +++ /dev/null @@ -1,2 +0,0 @@ -``make install`` no longer installs ``wininst-*.exe`` files used by -distutils bdist_wininst: bdist_wininst only works on Windows. diff --git a/Misc/NEWS.d/next/Build/2019-07-11-01-28-24.bpo-36044.gIgfiJ.rst = b/Misc/NEWS.d/next/Build/2019-07-11-01-28-24.bpo-36044.gIgfiJ.rst deleted file mode 100644 index 177c4cb6d17c7..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-07-11-01-28-24.bpo-36044.gIgfiJ.rst +++ /dev/null @@ -1,9 +0,0 @@ -Reduce the number of unit tests run for the PGO generation task. This -speeds up the task by a factor of about 15x. Running the full unit test -suite is slow. This change may result in a slightly less optimized build -since not as many code branches will be executed. If you are willing to -wait for the much slower build, the old behavior can be restored using -'./configure [..] PROFILE_TASK=3D"-m test --pgo-extended"'. We make no -guarantees as to which PGO task set produces a faster build. Users who -care should run their own relevant benchmarks as results can depend on -the environment, workload, and compiler tool chain. diff --git a/Misc/NEWS.d/next/Build/2019-07-29-11-36-16.bpo-37707.Sm-dGk.rst = b/Misc/NEWS.d/next/Build/2019-07-29-11-36-16.bpo-37707.Sm-dGk.rst deleted file mode 100644 index c0d58ab747b2b..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-07-29-11-36-16.bpo-37707.Sm-dGk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Mark some individual tests to skip when --pgo is used. The tests marked -increase the PGO task time significantly and likely don't help improve -optimization of the final executable. diff --git a/Misc/NEWS.d/next/Build/2019-07-30-16-26-11.bpo-37725.MkG1TT.rst = b/Misc/NEWS.d/next/Build/2019-07-30-16-26-11.bpo-37725.MkG1TT.rst deleted file mode 100644 index 1687cf223c414..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-07-30-16-26-11.bpo-37725.MkG1TT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Change "clean" makefile target to also clean the program guided optimization -(PGO) data. Previously you would have to use "make clean" and "make -profile-removal", or "make clobber". diff --git a/Misc/NEWS.d/next/Build/2019-08-24-00-29-40.bpo-37936.QrORqA.rst = b/Misc/NEWS.d/next/Build/2019-08-24-00-29-40.bpo-37936.QrORqA.rst deleted file mode 100644 index 4c6486103881a..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-08-24-00-29-40.bpo-37936.QrORqA.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :file:`.gitignore` file no longer applies to any files that are in fact -tracked in the Git repository. Patch by Greg Price. diff --git a/Misc/NEWS.d/next/Build/2019-08-24-17-39-09.bpo-37760.f3jXuH.rst = b/Misc/NEWS.d/next/Build/2019-08-24-17-39-09.bpo-37760.f3jXuH.rst deleted file mode 100644 index 04981733dbe96..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-08-24-17-39-09.bpo-37760.f3jXuH.rst +++ /dev/null @@ -1,6 +0,0 @@ -The :file:`Tools/unicode/makeunicodedata.py` script, which is used for -converting information from the Unicode Character Database into generated -code and data used by the methods of :class:`str` and by the -:mod:`unicodedata` module, now handles each character's data as a -``dataclass`` with named attributes, rather than a length-18 list of -different fields. diff --git a/Misc/NEWS.d/next/Build/2019-09-10-00-54-48.bpo-37936.E7XEwu.rst = b/Misc/NEWS.d/next/Build/2019-09-10-00-54-48.bpo-37936.E7XEwu.rst deleted file mode 100644 index 5ded61eafe947..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-09-10-00-54-48.bpo-37936.E7XEwu.rst +++ /dev/null @@ -1,5 +0,0 @@ -The :file:`.gitignore` file systematically keeps "rooted", with a -non-trailing slash, all the rules that are meant to apply to files in a -specific place in the repo. Previously, when the intended file to ignore -happened to be at the root of the repo, we'd most often accidentally also -ignore files and directories with the same name anywhere in the tree. diff --git a/Misc/NEWS.d/next/Build/2019-09-13-14-12-36.bpo-36002.Bcl4oe.rst = b/Misc/NEWS.d/next/Build/2019-09-13-14-12-36.bpo-36002.Bcl4oe.rst deleted file mode 100644 index 374e7b234cfe6..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-09-13-14-12-36.bpo-36002.Bcl4oe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Locate ``llvm-profdata`` and ``llvm-ar`` binaries using ``AC_PATH_TOOL`` -rather than ``AC_PATH_TARGET_TOOL``. diff --git a/Misc/NEWS.d/next/Build/2019-09-28-02-37-11.bpo-38301.123456.rst = b/Misc/NEWS.d/next/Build/2019-09-28-02-37-11.bpo-38301.123456.rst deleted file mode 100644 index 59c9a76385e2b..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-09-28-02-37-11.bpo-38301.123456.rst +++ /dev/null @@ -1,2 +0,0 @@ -In Solaris family, we must be sure to use ``-D_REENTRANT``. -Patch by Jes=C3=BAs Cea Avi=C3=B3n. diff --git a/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst = b/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst deleted file mode 100644 index 98f4a3bf4f545..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-10-11-15-32-58.bpo-37415.D9RXrq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix stdatomic.h header check for ICC compiler: the ICC implementation lacks -atomic_uintptr_t type which is needed by Python. diff --git a/Misc/NEWS.d/next/Build/2019-10-13-16-18-24.bpo-38468.buCO84.rst = b/Misc/NEWS.d/next/Build/2019-10-13-16-18-24.bpo-38468.buCO84.rst deleted file mode 100644 index 4fe4c2b25a1aa..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-10-13-16-18-24.bpo-38468.buCO84.rst +++ /dev/null @@ -1,2 +0,0 @@ -Misc/python-config.in now uses `getvar()` for all still existing `sysconfig.= get_config_var()` calls. -Patch by Joannah Nanjekye. diff --git a/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst = b/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst deleted file mode 100644 index c715ff9704127..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-11-04-14-30-37.bpo-38684.aed593.rst +++ /dev/null @@ -1 +0,0 @@ -Fix _hashlib build when Blake2 is disabled, but OpenSSL supports it. diff --git a/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst = b/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst deleted file mode 100644 index 10eaf844e8aaf..0000000000000 --- a/Misc/NEWS.d/next/Build/2019-11-15-09-25-44.bpo-38809.9jwta6.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, build scripts will now recognize and use python.exe from an -active virtual env. diff --git a/Misc/NEWS.d/next/C API/2018-08-04-00-59-44.bpo-34331.iaUkmU.rst = b/Misc/NEWS.d/next/C API/2018-08-04-00-59-44.bpo-34331.iaUkmU.rst deleted file mode 100644 index e45e0915dbf56..0000000000000 --- a/Misc/NEWS.d/next/C API/2018-08-04-00-59-44.bpo-34331.iaUkmU.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Use singular/plural noun in error message when instantiating an abstract -class with non-overriden abstract method(s). diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst = b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst deleted file mode 100644 index a7efce468c6d8..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Convert posixmodule.c statically allocated types ``DirEntryType`` and -``ScandirIteratorType`` to heap-allocated types. diff --git a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst = b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst deleted file mode 100644 index 7a35c9583d691..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Misc/NEWS.d/next/C API/2019-06-07-14-03-52.bpo-37194.uck7MD.rst = b/Misc/NEWS.d/next/C API/2019-06-07-14-03-52.bpo-37194.uck7MD.rst deleted file mode 100644 index c15d3720b010c..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-07-14-03-52.bpo-37194.uck7MD.rst=09 +++ /dev/null @@ -1,6 +0,0 @@ -Add a new public :c:func:`PyObject_CallNoArgs` function to the C API: call a -callable Python object without any arguments. It is the most efficient way to -call a callback without any argument. On x86-64, for example, -``PyObject_CallFunctionObjArgs(func, NULL)`` allocates 960 bytes on the stack -per call, whereas ``PyObject_CallNoArgs(func)`` only allocates 624 bytes per -call. diff --git a/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst = b/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst deleted file mode 100644 index 58038b21729b0..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix dtrace issue introduce by bpo-36842 diff --git a/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst = b/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst deleted file mode 100644 index 0ea8b9b867887..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-11-02-50-38.bpo-37221.4tClQT.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create -code objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount* -parameter for indicating the number of positonal-only arguments. diff --git a/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst = b/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst deleted file mode 100644 index 6d6c4ad4af607..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst=09 +++ /dev/null @@ -1 +0,0 @@ -The :const:`METH_FASTCALL` calling convention has been documented. diff --git a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst = b/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst deleted file mode 100644 index 63b355ecdb336..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-19-12-06-31.bpo-37337.gXIGyU.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add fast functions for calling methods: :c:func:`_PyObject_VectorcallMethod`, -:c:func:`_PyObject_CallMethodNoArgs` and :c:func:`_PyObject_CallMethodOneArg= `. diff --git a/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst = b/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst deleted file mode 100644 index 095d581163854..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-06-28-15-49-16.bpo-36763.zrmgki.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Add :func:`PyConfig_SetWideStringList` function. diff --git a/Misc/NEWS.d/next/C API/2019-07-02-15-42-37.bpo-37483.vftT4f.rst = b/Misc/NEWS.d/next/C API/2019-07-02-15-42-37.bpo-37483.vftT4f.rst deleted file mode 100644 index e2b0201e4ae93..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-02-15-42-37.bpo-37483.vftT4f.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add new function ``_PyObject_CallOneArg`` for calling an object with one -positional argument. diff --git a/Misc/NEWS.d/next/C API/2019-07-06-23-56-47.bpo-21120.lXHqlT.rst = b/Misc/NEWS.d/next/C API/2019-07-06-23-56-47.bpo-21120.lXHqlT.rst deleted file mode 100644 index 088a6a8614f3b..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-06-23-56-47.bpo-21120.lXHqlT.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Exclude Python-ast.h, ast.h and asdl.h from the limited API. diff --git a/Misc/NEWS.d/next/C API/2019-07-07-10-37-07.bpo-37207.SlVNky.rst = b/Misc/NEWS.d/next/C API/2019-07-07-10-37-07.bpo-37207.SlVNky.rst deleted file mode 100644 index 8df76614a0d73..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-07-10-37-07.bpo-37207.SlVNky.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The vectorcall protocol is now enabled for ``type`` objects: set -``tp_vectorcall`` to a vectorcall function to be used instead of ``tp_new`` -and ``tp_init`` when calling the class itself. diff --git a/Misc/NEWS.d/next/C API/2019-07-10-12-27-28.bpo-37540.E8Z773.rst = b/Misc/NEWS.d/next/C API/2019-07-10-12-27-28.bpo-37540.E8Z773.rst deleted file mode 100644 index 1a09c7e1330e5..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-10-12-27-28.bpo-37540.E8Z773.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The vectorcall protocol now requires that the caller passes only strings as -keyword names. diff --git a/Misc/NEWS.d/next/C API/2019-07-16-11-02-00.bpo-37151.YKfuNA.rst = b/Misc/NEWS.d/next/C API/2019-07-16-11-02-00.bpo-37151.YKfuNA.rst deleted file mode 100644 index 0841e570f6c91..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-16-11-02-00.bpo-37151.YKfuNA.rst=09 +++ /dev/null @@ -1 +0,0 @@ -``PyCFunction_Call`` is now a deprecated alias of :c:func:`PyObject_Call`. diff --git a/Misc/NEWS.d/next/C API/2019-07-17-09-50-50.bpo-29548.5wIptQ.rst = b/Misc/NEWS.d/next/C API/2019-07-17-09-50-50.bpo-29548.5wIptQ.rst deleted file mode 100644 index e7409191c0ef2..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-17-09-50-50.bpo-29548.5wIptQ.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The functions ``PyEval_CallObject``, ``PyEval_CallFunction``, -``PyEval_CallMethod`` and ``PyEval_CallObjectWithKeywords`` are deprecated. -Use :c:func:`PyObject_Call` and its variants instead. diff --git a/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst = b/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst deleted file mode 100644 index 2a6efaaaeafae..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-07-21-21-08-47.bpo-37645.4DcUaI.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add :c:func:`_PyObject_FunctionStr` to get a user-friendly string representa= tion -of a function-like object. Patch by Jeroen Demeyer. diff --git a/Misc/NEWS.d/next/C API/2019-08-17-13-50-21.bpo-37879.CZeUem.rst = b/Misc/NEWS.d/next/C API/2019-08-17-13-50-21.bpo-37879.CZeUem.rst deleted file mode 100644 index 87322fbf5f239..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-08-17-13-50-21.bpo-37879.CZeUem.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix subtype_dealloc to suppress the type decref when the base type is a C -heap type diff --git a/Misc/NEWS.d/next/C API/2019-08-23-11-35-55.bpo-37926.hnI5IQ.rst = b/Misc/NEWS.d/next/C API/2019-08-23-11-35-55.bpo-37926.hnI5IQ.rst deleted file mode 100644 index 20185330a8f4f..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-08-23-11-35-55.bpo-37926.hnI5IQ.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix a crash in ``PySys_SetArgvEx(0, NULL, 0)``. diff --git a/Misc/NEWS.d/next/C API/2019-08-23-18-45-11.bpo-36763.q3Kh8Z.rst = b/Misc/NEWS.d/next/C API/2019-08-23-18-45-11.bpo-36763.q3Kh8Z.rst deleted file mode 100644 index 500cdbf341172..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-08-23-18-45-11.bpo-36763.q3Kh8Z.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Options added by ``PySys_AddXOption()`` are now handled the same way than -``PyConfig.xoptions`` and command line ``-X`` options. diff --git a/Misc/NEWS.d/next/C API/2019-09-05-14-17-21.bpo-15088.plt8Em.rst = b/Misc/NEWS.d/next/C API/2019-09-05-14-17-21.bpo-15088.plt8Em.rst deleted file mode 100644 index 8a27afc9678a9..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-05-14-17-21.bpo-15088.plt8Em.rst=09 +++ /dev/null @@ -1,4 +0,0 @@ -The C function ``PyGen_NeedsFinalizing`` has been removed. It was not -documented, tested or used anywhere within CPython after the implementation -of :pep:`442`. Patch by Joannah Nanjekye. -(Patch by Joannah Nanjekye) \ No newline at end of file diff --git a/Misc/NEWS.d/next/C API/2019-09-13-01-24-47.bpo-38140.y59qaO.rst = b/Misc/NEWS.d/next/C API/2019-09-13-01-24-47.bpo-38140.y59qaO.rst deleted file mode 100644 index 7df1d25632b31..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-13-01-24-47.bpo-38140.y59qaO.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Make dict and weakref offsets opaque for C heap types by passing the offsets -through PyMemberDef diff --git a/Misc/NEWS.d/next/C API/2019-09-19-18-26-29.bpo-38205.Db1OJL.rst = b/Misc/NEWS.d/next/C API/2019-09-19-18-26-29.bpo-38205.Db1OJL.rst deleted file mode 100644 index 1818e54d461a4..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-19-18-26-29.bpo-38205.Db1OJL.rst=09 +++ /dev/null @@ -1 +0,0 @@ -The :c:func:`Py_UNREACHABLE` macro now calls :c:func:`Py_FatalError`. diff --git a/Misc/NEWS.d/next/C API/2019-09-20-17-22-41.bpo-38234.ZbquVK.rst = b/Misc/NEWS.d/next/C API/2019-09-20-17-22-41.bpo-38234.ZbquVK.rst deleted file mode 100644 index fe658ad75d89e..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-20-17-22-41.bpo-38234.ZbquVK.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Python ignored arguments passed to :c:func:`Py_SetPath`, -:c:func:`Py_SetPythonHome` and :c:func:`Py_SetProgramName`: fix Python -initialization to use specified arguments. diff --git a/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst = b/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst deleted file mode 100644 index ba4cc312e6928..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-24-17-09-48.bpo-38234.d0bhEA.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -:c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full -path (:c:func:`Py_GetProgramFullPath`) rather than to the program name -(:c:func:`Py_GetProgramName`). diff --git a/Misc/NEWS.d/next/C API/2019-09-30-16-53-30.bpo-38303.YoIs0M.rst = b/Misc/NEWS.d/next/C API/2019-09-30-16-53-30.bpo-38303.YoIs0M.rst deleted file mode 100644 index 03048bbfce533..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-09-30-16-53-30.bpo-38303.YoIs0M.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Update audioop extension module to use the stable ABI (PEP-384). Patch by Ty= ler Kieft. diff --git a/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst = b/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst deleted file mode 100644 index 3b4c4232eb897..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-10-03-12-53-53.bpo-38266.0FIC1q.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Revert the removal of PyThreadState_DeleteCurrent() with documentation. \ No newline at end of file diff --git a/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst = b/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst deleted file mode 100644 index 6c42882cdbaa6..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-10-07-17-15-09.bpo-36389.hFX_jD.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The ``_PyObject_CheckConsistency()`` function is now also available in relea= se -mode. For example, it can be used to debug a crash in the ``visit_decref()`` -function of the GC. diff --git a/Misc/NEWS.d/next/C API/2019-10-08-01-23-24.bpo-38395.MJ6Ey9.rst = b/Misc/NEWS.d/next/C API/2019-10-08-01-23-24.bpo-38395.MJ6Ey9.rst deleted file mode 100644 index 4bc30600ca758..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-10-08-01-23-24.bpo-38395.MJ6Ey9.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fix a crash in :class:`weakref.proxy` objects due to incorrect lifetime -management when calling some associated methods that may delete the last -reference to object being referenced by the proxy. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst = b/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst deleted file mode 100644 index 1d73ad8fe96e6..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-10-21-09-24-03.bpo-38540.314N_T.rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fixed possible leak in :c:func:`PyArg_Parse` and similar functions for -format units ``"es#"`` and ``"et#"`` when the macro -:c:macro:`PY_SSIZE_T_CLEAN` is not defined. diff --git a/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst = b/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst deleted file mode 100644 index 55b9c13ca3d0c..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-10-30-22-03-03.bpo-38650.0pi8zt.rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The global variable :c:data:`PyStructSequence_UnnamedField` is now a -constant and refers to a constant string. diff --git a/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst = b/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst deleted file mode 100644 index b94f505568f41..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-11-04-17-59-46.bpo-38644.euO_RR.rst=09 +++ /dev/null @@ -1,5 +0,0 @@ -Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` -as regular functions for the limited API. Previously, there were defined as -macros, but these macros didn't work with the limited API which cannot access -``PyThreadState.recursion_depth`` field. Remove ``_Py_CheckRecursionLimit`` -from the stable ABI. diff --git a/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst = b/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst deleted file mode 100644 index fdf6abbf1c649..0000000000000 --- a/Misc/NEWS.d/next/C API/2019-11-04-21-10-47.bpo-37633.oOGVdo.rst=09 +++ /dev/null @@ -1 +0,0 @@ -Re=C3=ABxport some function compatibility wrappers for macros in ``pythonrun= .h``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-07-01-01-20.bpo-30773= .C31rVE.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-07-01-01-20.bpo-3077= 3.C31rVE.rst deleted file mode 100644 index 501ee527e8a9f..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-06-07-01-01-20.bpo-30773.C31rVE= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Prohibit parallel running of aclose() / asend() / athrow(). Fix ag_running -to reflect the actual running status of the AG. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-27575= .mMYgzv.rst b/Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-2757= 5.mMYgzv.rst deleted file mode 100644 index 2c250dcceb282..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-27575.mMYgzv= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Improve speed of dictview intersection by directly using set intersection -logic. Patch by David Su. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-19072= .Gc59GS.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-1907= 2.Gc59GS.rst deleted file mode 100644 index 1d27789420e04..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-19072.Gc59GS= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The :class:`classmethod` decorator can now wrap other descriptors -such as property objects. Adapted from a patch written by Graham -Dumpleton. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551= .oF5pbO.rst b/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-3555= 1.oF5pbO.rst deleted file mode 100644 index bd7946e6d9477..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Updated encodings: -- Removed the "tis260" encoding, which was an alias for the nonexistent "tac= tis" codec. -- Added "mac_centeuro" as an alias for the mac_latin2 encoding. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-15-20-42-36.bpo-20523= .rRLrvr.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-15-20-42-36.bpo-2052= 3.rRLrvr.rst deleted file mode 100644 index 91397c243b9f2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-15-20-42-36.bpo-20523.rRLrvr= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper and Dan=20 -Lidral-Porter. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556= .o9kfpu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-3455= 6.o9kfpu.rst deleted file mode 100644 index 7861eac5cb256..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-05-18-09-40.bpo-34556.o9kfpu= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Add ``--upgrade-deps`` to venv module. Patch by Cooper Ry Lees diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-09-59-31.bpo-36781= .uocWt6.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-09-59-31.bpo-3678= 1.uocWt6.rst deleted file mode 100644 index 2e9dcdcb9034c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-09-59-31.bpo-36781.uocWt6= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -:func:`sum` has been optimized for boolean values. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077= .S1h0Fc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-3707= 7.S1h0Fc.rst deleted file mode 100644 index 832dfc94ac49e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`threading.get_native_id` support for AIX. -Patch by M. Felt diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160= .O3IAY3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-3716= 0.O3IAY3.rst deleted file mode 100644 index c2fc6804a1268..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -:func:`threading.get_native_id` now also supports NetBSD. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974= .wdzzym.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-3697= 4.wdzzym.rst deleted file mode 100644 index 035cdd3d6a9e7..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-11-00-55.bpo-36974.wdzzym= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The slot ``tp_vectorcall_offset`` is inherited unconditionally to support -``super().__call__()`` when the base class uses vectorcall. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922= .EMZ3TF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-3692= 2.EMZ3TF.rst deleted file mode 100644 index c2a2ad4e8e737..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-13-59-52.bpo-36922.EMZ3TF= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` i= nstead of only instances of ``function``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-20-52-38.bpo-15913= .5Sg5cv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-06-20-52-38.bpo-1591= 3.5Sg5cv.rst deleted file mode 100644 index 0fbfcb37abb45..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-06-20-52-38.bpo-15913.5Sg5cv= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Implement :c:func:`PyBuffer_SizeFromFormat()` function (previously -documented but not implemented): call :func:`struct.calcsize`. -Patch by Joannah Nanjekye. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219= .jPSufq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-3721= 9.jPSufq.rst deleted file mode 100644 index d45f08610b21b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Remove erroneous optimization for empty set differences. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213= .UPii5K.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-3721= 3.UPii5K.rst deleted file mode 100644 index b949883da9c2b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Handle correctly negative line offsets in the peephole optimizer. Patch by -Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-12-59-38.bpo-36974= .bVYmSA.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-11-12-59-38.bpo-3697= 4.bVYmSA.rst deleted file mode 100644 index 6080ef361814a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-12-59-38.bpo-36974.bVYmSA= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Implemented separate vectorcall functions for every calling convention of -builtin functions and methods. This improves performance for calls. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231= .LF41Es.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-3723= 1.LF41Es.rst deleted file mode 100644 index 2e277194f3c2d..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The dispatching of type slots to special methods (for example calling -``__mul__`` when doing ``x * y``) has been made faster. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257= .IMxDvT.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-3725= 7.IMxDvT.rst deleted file mode 100644 index ac8d90fd2998b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Python's small object allocator (``obmalloc.c``) now allows (no more than) o= ne empty arena to remain available for immediate reuse, without returning it = to the OS. This prevents thrashing in simple loops where an arena could be c= reated and destroyed anew on each iteration. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-13-12-55-38.bpo-20443= .bQWAxg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-13-12-55-38.bpo-2044= 3.bQWAxg.rst deleted file mode 100644 index 3ec1aaf838304..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-13-12-55-38.bpo-20443.bQWAxg= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Python now gets the absolute path of the script filename specified on the -command line (ex: "python3 script.py"): the __file__ attribute of the __main= __ -module and sys.path[0] become an absolute path, rather than a relative path. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269= .SjVVAe.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-3726= 9.SjVVAe.rst deleted file mode 100644 index b9b79066774f8..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the peephole optimizer that was not treating correctly constant -conditions with binary operators. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300= .WJkgKV.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-3730= 0.WJkgKV.rst deleted file mode 100644 index aae278e849810..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Remove an unnecssary Py_XINCREF in classobject.c. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316= .LytDX_.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-3731= 6.LytDX_.rst deleted file mode 100644 index 40436d467c853..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-03-53-16.bpo-37316.LytDX_= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224= .FHWPGv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-3522= 4.FHWPGv.rst deleted file mode 100644 index 5a1a79be098ac..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-17-06-03-55.bpo-35224.FHWPGv= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Reverse evaluation order of key: value in dict comprehensions as proposed in= PEP 572. -I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-18-17-53-06.bpo-37330= .wAvHmz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-18-17-53-06.bpo-3733= 0.wAvHmz.rst deleted file mode 100644 index aec6d018600a5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-18-17-53-06.bpo-37330.wAvHmz= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -:func:`open`, :func:`io.open`, :func:`codecs.open` and -:class:`fileinput.FileInput` no longer accept ``'U'`` ("universal newline") = in -the file mode. This flag was deprecated since Python 3.3. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214= .hIiHeD.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-2421= 4.hIiHeD.rst deleted file mode 100644 index 2d70ce05deaed..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-22-12-45-20.bpo-24214.hIiHeD= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 -incremental decoders. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-23-00-26-30.bpo-37348= .pp8P-x.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-23-00-26-30.bpo-3734= 8.pp8P-x.rst deleted file mode 100644 index 5859837d23685..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-23-00-26-30.bpo-37348.pp8P-x= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Optimized decoding short ASCII string with UTF-8 and ascii codecs. -``b"foo".decode()`` is about 15% faster. Patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-24-21-53-52.bpo-37388= .0XTZmW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-24-21-53-52.bpo-3738= 8.0XTZmW.rst deleted file mode 100644 index 295ef1bdf529b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-24-21-53-52.bpo-37388.0XTZmW= .rst=09 +++ /dev/null @@ -1,7 +0,0 @@ -In development mode and in debug build, *encoding* and *errors* arguments are -now checked on string encoding and decoding operations. Examples: :func:`ope= n`, -:meth:`str.encode` and :meth:`bytes.decode`. - -By default, for best performances, the *errors* argument is only checked at = the -first encoding/decoding error, and the *encoding* argument is sometimes igno= red -for empty strings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-25-01-45-06.bpo-37392= .J3JhIx.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-25-01-45-06.bpo-3739= 2.J3JhIx.rst deleted file mode 100644 index 97ab98c141ad9..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-25-01-45-06.bpo-37392.J3JhIx= .rst=09 +++ /dev/null @@ -1,4 +0,0 @@ -Remove ``sys.getcheckinterval()`` and ``sys.setcheckinterval()`` functions. -They were deprecated since Python 3.2. Use :func:`sys.getswitchinterval` and -:func:`sys.setswitchinterval` instead. Remove also ``check_interval`` field = of -the ``PyInterpreterState`` structure. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-17-27-26.bpo-37414= .o6Lnbc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-26-17-27-26.bpo-3741= 4.o6Lnbc.rst deleted file mode 100644 index a3ff57b36b6db..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-17-27-26.bpo-37414.o6Lnbc= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The undocumented ``sys.callstats()`` function has been removed. Since Python -3.7, it was deprecated and always returned ``None``. It required a special -build option ``CALL_PROFILE`` which was already removed in Python 3.7. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417= .VsZeHL.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-3741= 7.VsZeHL.rst deleted file mode 100644 index f004631e23610..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-26-18-41-00.bpo-37417.VsZeHL= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`bytearray.extend` now correctly handles errors that arise during iter= ation. -Patch by Brandt Bucher. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-27-15-01-14.bpo-37433= .amNGqr.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-27-15-01-14.bpo-3743= 3.amNGqr.rst deleted file mode 100644 index 794ddbbfec734..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-27-15-01-14.bpo-37433.amNGqr= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix ``SyntaxError`` indicator printing too many spaces for multi-line string= s - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467= .u-XyEu.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-3746= 7.u-XyEu.rst deleted file mode 100644 index 5e809646b4b86..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-01-12-22-44.bpo-37467.u-XyEu= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a -bytes string. For example, for a SyntaxError exception where the filename -attribute is a bytes string. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537= .OkB0wd.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-3753= 7.OkB0wd.rst deleted file mode 100644 index abf874475d6d9..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-10-09-56-47.bpo-37537.OkB0wd= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Compute allocated pymalloc blocks inside _Py_GetAllocatedBlocks(). This -slows down _Py_GetAllocatedBlocks() but gives a small speedup to -_PyObject_Malloc() and _PyObject_Free(). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-10-20-33-53.bpo-37543= .EvI19D.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-10-20-33-53.bpo-3754= 3.EvI19D.rst deleted file mode 100644 index 3f74bbc5d0716..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-10-20-33-53.bpo-37543.EvI19D= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Optimized pymalloc for non PGO build. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-14-23-57-27.bpo-37593= .yHSTwH.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-14-23-57-27.bpo-3759= 3.yHSTwH.rst deleted file mode 100644 index 5ec9bba2d2b9e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-14-23-57-27.bpo-37593.yHSTwH= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Swap the positions of the *posonlyargs* and *args* parameters in the -constructor of :class:`ast.parameters` nodes. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-18-11-50-49.bpo-37619= .X6Lulo.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-18-11-50-49.bpo-3761= 9.X6Lulo.rst deleted file mode 100644 index 8723d3d9e9da0..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-18-11-50-49.bpo-37619.X6Lulo= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -When adding a wrapper descriptor from one class to a different class -(for example, setting ``__add__ =3D str.__add__`` on an ``int`` subclass), -an exception is correctly raised when the operator is called. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-20-22-34-42.bpo-37444= .UOd3Xs.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-20-22-34-42.bpo-3744= 4.UOd3Xs.rst deleted file mode 100644 index 67c68071a8398..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-20-22-34-42.bpo-37444.UOd3Xs= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Update differing exception between :meth:`builtins.__import__` and :meth:`im= portlib.__import__`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-22-11-05-05.bpo-37648= .6TY2L-.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-22-11-05-05.bpo-3764= 8.6TY2L-.rst deleted file mode 100644 index 3c11d3d6008e7..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-22-11-05-05.bpo-37648.6TY2L-= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fixed minor inconsistency in :meth:`list.__contains__`, -:meth:`tuple.__contains__` and a few other places. The collection's item is -now always at the left and the needle is on the right of ``=3D=3D``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340= .5ktLEg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-3734= 0.5ktLEg.rst deleted file mode 100644 index e61146b6f797e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-07-25-11-06-57.bpo-37340.5ktLEg= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Removed object cache (``free_list``) for bound method objects. Temporary -bound method objects are less used than before thanks to the ``LOAD_METHOD`` -opcode and the ``_PyObject_VectorcallMethod`` C API. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-01-10-45-51.bpo-34880= .u_x_CG.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-01-10-45-51.bpo-3488= 0.u_x_CG.rst deleted file mode 100644 index 31c42cb2e4ccd..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-01-10-45-51.bpo-34880.u_x_CG= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The :keyword:`assert` statement now works properly if the -:exc:`AssertionError` exception is being shadowed. -Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-02-15-01-33.bpo-36311= .uY5vt-.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-02-15-01-33.bpo-3631= 1.uY5vt-.rst deleted file mode 100644 index c45f2224237b5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-02-15-01-33.bpo-36311.uY5vt-= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Decoding bytes objects larger than 2GiB is faster and no longer fails when a -multibyte characters spans a chunk boundary. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-04-12-24-18.bpo-36279= .8Zy7jZ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-04-12-24-18.bpo-3627= 9.8Zy7jZ.rst deleted file mode 100644 index 0d045c5f40e04..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-04-12-24-18.bpo-36279.8Zy7jZ= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix potential use of uninitialized memory in :func:`os.wait3`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-05-14-22-59.bpo-37757= .lRv5HX.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-05-14-22-59.bpo-3775= 7.lRv5HX.rst deleted file mode 100644 index 258df0dc09bdc..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-05-14-22-59.bpo-37757.lRv5HX= .rst=09 +++ /dev/null @@ -1,7 +0,0 @@ -:pep:`572`: As described in the PEP, assignment expressions now raise -:exc:`SyntaxError` when their interaction with comprehension scoping results -in an ambiguous target scope. - -The ``TargetScopeError`` subclass originally proposed by the PEP has been -removed in favour of just raising regular syntax errors for the disallowed -cases. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912= .UDwSMJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-3291= 2.UDwSMJ.rst deleted file mode 100644 index e18d8adfbee9e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-06-14-03-59.bpo-32912.UDwSMJ= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of -:exc:`DeprecationWarning` for invalid escape sequences in string and bytes -literals. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-06-23-39-05.bpo-37409= .1qwzn2.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-06-23-39-05.bpo-3740= 9.1qwzn2.rst deleted file mode 100644 index 9cfa715480201..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-06-23-39-05.bpo-37409.1qwzn2= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Ensure explicit relative imports from interactive sessions and scripts (havi= ng no parent package) always raise ImportError, rather than treating the curr= ent module as the package. -Patch by Ben Lewis. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-09-18-28-57.bpo-37802= .pKxcAW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-09-18-28-57.bpo-3780= 2.pKxcAW.rst deleted file mode 100644 index dc0a23851eaf7..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-09-18-28-57.bpo-37802.pKxcAW= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Slightly improve performance of :c:func:`PyLong_FromUnsignedLong`, -:c:func:`PyLong_FromUnsignedLongLong` and :c:func:`PyLong_FromSize_t`. -Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840= .elLCci.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-3784= 0.elLCci.rst deleted file mode 100644 index df689dade9a49..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix handling of negative indices in :c:member:`~PySequenceMethods.sq_item` -of :class:`bytearray`. Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-15-12-48-36.bpo-20490= .-hXeEn.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-15-12-48-36.bpo-2049= 0.-hXeEn.rst deleted file mode 100644 index dfee480e1aa70..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-15-12-48-36.bpo-20490.-hXeEn= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Improve import error message for partially initialized module on circular -``from`` imports - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-17-18-41-59.bpo-37830= .fNfMbz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-17-18-41-59.bpo-3783= 0.fNfMbz.rst deleted file mode 100644 index 76f4bf671d1c0..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-17-18-41-59.bpo-37830.fNfMbz= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fixed compilation of :keyword:`break` and :keyword:`continue` in the -:keyword:`finally` block when the corresponding :keyword:`try` block -contains :keyword:`return` with a non-constant value. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-20-04-36-37.bpo-37751= .CSFzUd.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-20-04-36-37.bpo-3775= 1.CSFzUd.rst deleted file mode 100644 index 4da59ff4c1c95..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-20-04-36-37.bpo-37751.CSFzUd= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix :func:`codecs.lookup` to normalize the encoding name the same way than := func:`encodings.normalize_encoding`, except that :func:`codecs.lookup` also c= onverts the name to lower case. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-23-22-46-25.bpo-37812= .vsWZwS.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-23-22-46-25.bpo-3781= 2.vsWZwS.rst deleted file mode 100644 index f1085a1791c81..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-23-22-46-25.bpo-37812.vsWZwS= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -The ``CHECK_SMALL_INT`` macro used inside :file:`Object/longobject.c` has -been replaced with an explicit ``return`` at each call site. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-26-04-09-57.bpo-37947= .mzAQtB.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-26-04-09-57.bpo-3794= 7.mzAQtB.rst deleted file mode 100644 index 2b3b72367030d..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-26-04-09-57.bpo-37947.mzAQtB= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Adjust correctly the recursion level in the symtable generation for named -expressions. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-27-21-21-36.bpo-37966= .5OBLez.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-27-21-21-36.bpo-3796= 6.5OBLez.rst deleted file mode 100644 index 6b9d69c5b3a9a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-27-21-21-36.bpo-37966.5OBLez= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -The implementation of :func:`~unicodedata.is_normalized` has been greatly -sped up on strings that aren't normalized, by implementing the full -normalization-quick-check algorithm from the Unicode standard. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-29-01-55-38.bpo-8425.= FTq4A8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-29-01-55-38.bpo-8425.= FTq4A8.rst deleted file mode 100644 index 8e5ec0bfe874b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-29-01-55-38.bpo-8425.FTq4A8.= rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Optimize set difference_update for the case when the other set is much -larger than the base set. (Suggested by Evgeny Kapun with code contributed -by Michele Orr=C3=B9). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-31-11-13-25.bpo-37994= .Rj6S4j.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-31-11-13-25.bpo-3799= 4.Rj6S4j.rst deleted file mode 100644 index 103ac5a309057..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-08-31-11-13-25.bpo-37994.Rj6S4j= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fixed silencing arbitrary errors if an attribute lookup fails in several -sites. Only AttributeError should be silenced. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-02-16-17-42.bpo-36946= ._lAuSR.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-02-16-17-42.bpo-3694= 6._lAuSR.rst deleted file mode 100644 index e0c5d712f0010..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-02-16-17-42.bpo-36946._lAuSR= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fix possible signed integer overflow when handling slices. Patch by hongweip= eng. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-02-20-00-31.bpo-38005= .e7VsTA.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-02-20-00-31.bpo-3800= 5.e7VsTA.rst deleted file mode 100644 index 706abf587b90a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-02-20-00-31.bpo-38005.e7VsTA= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Fixed comparing and creating of InterpreterID and ChannelID. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-44-17.bpo-38071= .bLwkBJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-44-17.bpo-3807= 1.bLwkBJ.rst deleted file mode 100644 index 327bf73bfd45b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-44-17.bpo-38071.bLwkBJ= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Make termios extension module PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069= .cn8XLv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-3806= 9.cn8XLv.rst deleted file mode 100644 index 6bfe7a744f6ee..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Make _posixsubprocess PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-00-42.bpo-38072= .Y1xpDO.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-00-42.bpo-3807= 2.Y1xpDO.rst deleted file mode 100644 index 2860e69ea496c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-00-42.bpo-38072.Y1xpDO= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -grp module made PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073= .ZoKYOU.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-3807= 3.ZoKYOU.rst deleted file mode 100644 index d59630f888085..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Make pwd extension module PEP-384 compatible diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074= .MsVbeI.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-3807= 4.MsVbeI.rst deleted file mode 100644 index a20b40e750b07..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -zlib module made PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-59-50.bpo-38075= .N8OZKF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-59-50.bpo-3807= 5.N8OZKF.rst deleted file mode 100644 index 015951b96b67c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-59-50.bpo-38075.N8OZKF= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -The random module is now PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-16-36-37.bpo-38076= .C5dVBl.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-16-36-37.bpo-3807= 6.C5dVBl.rst deleted file mode 100644 index 6f18c03403d2c..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-16-36-37.bpo-38076.C5dVBl= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -The struct module is now PEP-384 compatible \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-10-02.bpo-38113= .yZXC3P.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-10-02.bpo-3811= 3.yZXC3P.rst deleted file mode 100644 index af1210de4242d..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-10-02.bpo-38113.yZXC3P= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -ast module updated to PEP-384 and all statics removed \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116= .KDwmwt.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-3811= 6.KDwmwt.rst deleted file mode 100644 index d6d630b64b050..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-11-14-49-42.bpo-38116.KDwmwt= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -The select module is now PEP-384 compliant and no longer has static state \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-12-00-14-01.bpo-38124= .n6E0H7.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-12-00-14-01.bpo-3812= 4.n6E0H7.rst deleted file mode 100644 index dca0ba5bc0cc3..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-12-00-14-01.bpo-38124.n6E0H7= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix an off-by-one error in PyState_AddModule that could cause out-of-bounds -memory access. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-12-19-50-01.bpo-38013= .I7btD0.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-12-19-50-01.bpo-3801= 3.I7btD0.rst deleted file mode 100644 index a61aa48ff1efc..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-12-19-50-01.bpo-38013.I7btD0= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Allow to call ``async_generator_athrow().throw(...)`` even for non-started -async generator helper. It fixes annoying warning at the end of -:func:`asyncio.run` call. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-20-19-06-23.bpo-38236= .eQ0Tmj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-20-19-06-23.bpo-3823= 6.eQ0Tmj.rst deleted file mode 100644 index 5c7729296cee5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-20-19-06-23.bpo-38236.eQ0Tmj= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Python now dumps path configuration if it fails to import the Python codecs -of the filesystem and stdio encodings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-22-13-56-18.bpo-38219= .rFl7JD.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-22-13-56-18.bpo-3821= 9.rFl7JD.rst deleted file mode 100644 index 8d621cfb826ab..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-22-13-56-18.bpo-38219.rFl7JD= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Optimized the :class:`dict` constructor and the :meth:`~dict.update` method -for the case when the argument is a dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-24-05-32-27.bpo-11410= .vS182p.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-24-05-32-27.bpo-1141= 0.vS182p.rst deleted file mode 100644 index 2b572ad20f9a5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-24-05-32-27.bpo-11410.vS182p= .rst=09 +++ /dev/null @@ -1,4 +0,0 @@ -Better control over symbol visibility is provided through use of the -visibility attributes available in gcc >=3D 4.0, provided in a uniform way -across POSIX and Windows. The POSIX build files have been updated to compile -with -fvisibility=3Dhidden, minimising exported symbols. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-24-18-45-46.bpo-36871= .p47knk.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-24-18-45-46.bpo-3687= 1.p47knk.rst deleted file mode 100644 index 6b7b19a0d57ee..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-24-18-45-46.bpo-36871.p47knk= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Improve error handling for the assert_has_calls and assert_has_awaits method= s of -mocks. Fixed a bug where any errors encountered while binding the expected c= alls -to the mock's spec were silently swallowed, leading to misleading error outp= ut. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-28-22-54-25.bpo-38310= .YDTbEo.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-28-22-54-25.bpo-3831= 0.YDTbEo.rst deleted file mode 100644 index 5c3086b607d03..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-28-22-54-25.bpo-38310.YDTbEo= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Predict ``BUILD_MAP_UNPACK_WITH_CALL`` -> ``CALL_FUNCTION_EX`` opcode pairs = in the main interpreter loop. Patch by Brandt Bucher. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-30-00-56-21.bpo-38317= .pmqlIQ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-30-00-56-21.bpo-3831= 7.pmqlIQ.rst deleted file mode 100644 index b6d07474cf520..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-30-00-56-21.bpo-38317.pmqlIQ= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix warnings options priority: ``PyConfig.warnoptions`` has the highest -priority, as stated in the :pep:`587`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006= .UYlJum.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-3800= 6.UYlJum.rst deleted file mode 100644 index c2dafae0afabe..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006.UYlJum= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug due to the interaction of weakrefs and the cyclic garbage -collector. We must clear any weakrefs in garbage in order to prevent their -callbacks from executing and causing a crash. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-01-12-46-30.bpo-37474= .cB3se1.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-01-12-46-30.bpo-3747= 4.cB3se1.rst deleted file mode 100644 index c259f81a3d7d4..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-01-12-46-30.bpo-37474.cB3se1= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -On FreeBSD, Python no longer calls ``fedisableexcept()`` at startup to -control the floating point control mode. The call became useless since -FreeBSD 6: it became the default mode. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-05-19-36-16.bpo-38402= .EZuzgK.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-05-19-36-16.bpo-3840= 2.EZuzgK.rst deleted file mode 100644 index 8331500bf1a3e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-05-19-36-16.bpo-38402.EZuzgK= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -Check the error from the system's underlying ``crypt`` or ``crypt_r``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-06-15-01-57.bpo-38210= .Xgc6F_.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-06-15-01-57.bpo-3821= 0.Xgc6F_.rst deleted file mode 100644 index 768c6d4e644a5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-06-15-01-57.bpo-38210.Xgc6F_= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Remove unecessary intersection and update set operation in dictview with -empty set. (Contributed by Dong-hee Na in :issue:`38210`.) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-07-22-51-39.bpo-38392= .KaXXps.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-07-22-51-39.bpo-3839= 2.KaXXps.rst deleted file mode 100644 index 07358ece753f5..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-07-22-51-39.bpo-38392.KaXXps= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -In debug mode, :c:func:`PyObject_GC_Track` now calls ``tp_traverse()`` of -the object type to ensure that the object is valid: test that objects -visited by ``tp_traverse()`` are valid. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-09-16-50-52.bpo-38379= .oz5qZx.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-09-16-50-52.bpo-3837= 9.oz5qZx.rst deleted file mode 100644 index 82dcb525dd49d..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-09-16-50-52.bpo-38379.oz5qZx= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -When cyclic garbage collection (gc) runs finalizers that resurrect unreachab= le objects, the current gc run ends, without collecting any cyclic trash. Ho= wever, the statistics reported by ``collect()`` and ``get_stats()`` claimed t= hat all cyclic trash found was collected, and that the resurrected objects we= re collected. Changed the stats to report that none were collected. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-10-01-41-02.bpo-38379= ._q4dhn.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-10-01-41-02.bpo-3837= 9._q4dhn.rst deleted file mode 100644 index 86f908b67740b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-10-01-41-02.bpo-38379._q4dhn= .rst=09 +++ /dev/null @@ -1,4 +0,0 @@ -When the garbage collector makes a collection in which some objects -resurrect (they are reachable from outside the isolated cycles after the -finalizers have been executed), do not block the collection of all objects -that are still unreachable. Patch by Pablo Galindo and Tim Peters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-10-20-42-09.bpo-38437= .z_0mZp.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-10-20-42-09.bpo-3843= 7.z_0mZp.rst deleted file mode 100644 index 69a8843ce0f69..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-10-20-42-09.bpo-38437.z_0mZp= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Activate the ``GC_DEBUG`` macro for debug builds of the interpreter (when -``Py_DEBUG`` is set). Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-13-23-41-38.bpo-38469= .9kmuQj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-13-23-41-38.bpo-3846= 9.9kmuQj.rst deleted file mode 100644 index 328a1b70825af..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-13-23-41-38.bpo-38469.9kmuQj= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a bug where the scope of named expressions was not being resolved -correctly in the presence of the *global* keyword. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-19-12-44-13.bpo-38465= .V1L8c4.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-19-12-44-13.bpo-3846= 5.V1L8c4.rst deleted file mode 100644 index 4f77ebbfd02b8..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-19-12-44-13.bpo-38465.V1L8c4= .rst=09 +++ /dev/null @@ -1 +0,0 @@ -:class:`bytearray`, :class:`~array.array` and :class:`~mmap.mmap` objects al= low now to export more than 2**31 buffers at a time. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525= .Vty1cA.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-3852= 5.Vty1cA.rst deleted file mode 100644 index c74d143762253..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-00-36-18.bpo-38525.Vty1cA= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fix a segmentation fault when using reverse iterators of empty ``dict`` obje= cts. -Patch by Dong-hee Na and Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535= .ESMkVN.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-3853= 5.ESMkVN.rst deleted file mode 100644 index 7671fd06474ba..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-20-12-43-48.bpo-38535.ESMkVN= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Fixed line numbers and column offsets for AST nodes for calls without -arguments in decorators. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029= .AmRMEF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-2802= 9.AmRMEF.rst deleted file mode 100644 index 420e53aec9be0..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-09-38-54.bpo-28029.AmRMEF= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -``"".replace("", s, n)`` now returns ``s`` instead of an empty string for -all non-zero ``n``. There are similar changes for :class:`bytes` and -:class:`bytearray` objects. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613= .V_R3NC.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-3861= 3.V_R3NC.rst deleted file mode 100644 index c001db6679831..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-15-44-24.bpo-38613.V_R3NC= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of -``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but -they are almost same performance for now. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-25-25.bpo-38640= .4sAFh5.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-25-25.bpo-3864= 0.4sAFh5.rst deleted file mode 100644 index d99db3cce49a6..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-25-25.bpo-38640.4sAFh5= .rst=09 +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a bug in the compiler that was causing to raise in the presence of -break statements and continue statements inside always false while loops. -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639= .9-vKtO.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-3863= 9.9-vKtO.rst deleted file mode 100644 index 4432afde64d6e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-10-30-11-31-47.bpo-38639.9-vKtO= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Optimized :func:`math.floor()`, :func:`math.ceil()` and :func:`math.trunc()` -for floats. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631= .tRHaAk.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-3863= 1.tRHaAk.rst deleted file mode 100644 index d05ad05941ecf..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-11-18-17-10-20.bpo-38631.tRHaAk= .rst=09 +++ /dev/null @@ -1,2 +0,0 @@ -Replace ``Py_FatalError()`` call with a regular :exc:`RuntimeError` -exception in :meth:`float.__getformat__`. diff --git a/Misc/NEWS.d/next/Documentation/2018-06-02-12-55-23.bpo-25237.m8-= JMu.rst b/Misc/NEWS.d/next/Documentation/2018-06-02-12-55-23.bpo-25237.m8-JMu= .rst deleted file mode 100644 index 5778f377aeaf7..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-06-02-12-55-23.bpo-25237.m8-JMu.rst +++ /dev/null @@ -1 +0,0 @@ -Add documentation for tkinter modules diff --git a/Misc/NEWS.d/next/Documentation/2018-07-31-15-38-26.bpo-34293.yHu= pAL.rst b/Misc/NEWS.d/next/Documentation/2018-07-31-15-38-26.bpo-34293.yHupAL= .rst deleted file mode 100644 index 912a3ad48d403..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-07-31-15-38-26.bpo-34293.yHupAL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the Doc/Makefile regarding PAPER environment variable and PDF builds diff --git a/Misc/NEWS.d/next/Documentation/2018-10-26-18-10-29.bpo-33944.V1Y= eOA.rst b/Misc/NEWS.d/next/Documentation/2018-10-26-18-10-29.bpo-33944.V1YeOA= .rst deleted file mode 100644 index 29bec88c96495..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-10-26-18-10-29.bpo-33944.V1YeOA.rst +++ /dev/null @@ -1 +0,0 @@ -Added a note about the intended use of code in .pth files. diff --git a/Misc/NEWS.d/next/Documentation/2019-01-21-14-30-59.bpo-35803.yae= 6Lq.rst b/Misc/NEWS.d/next/Documentation/2019-01-21-14-30-59.bpo-35803.yae6Lq= .rst deleted file mode 100644 index b8394560e5486..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-01-21-14-30-59.bpo-35803.yae6Lq.rst +++ /dev/null @@ -1,2 +0,0 @@ -Document and test that ``tempfile`` functions may accept a -:term:`path-like object` for the ``dir`` argument. Patch by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Documentation/2019-02-14-07-12-48.bpo-23460.Iqi= qtm.rst b/Misc/NEWS.d/next/Documentation/2019-02-14-07-12-48.bpo-23460.Iqiqtm= .rst deleted file mode 100644 index 4674d551d3797..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-02-14-07-12-48.bpo-23460.Iqiqtm.rst +++ /dev/null @@ -1 +0,0 @@ -The documentation for decimal string formatting using the `:g` specifier has= been updated to reflect the correct exponential notation cutoff point. Origi= nal patch contributed by Tuomas Suutari. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-04-02-19-23-00.bpo-36487.Jg6= -MG.rst b/Misc/NEWS.d/next/Documentation/2019-04-02-19-23-00.bpo-36487.Jg6-MG= .rst deleted file mode 100644 index c8eb05b6c79cb..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-04-02-19-23-00.bpo-36487.Jg6-MG.rst +++ /dev/null @@ -1 +0,0 @@ -Make C-API docs clear about what the "main" interpreter is. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-05-18-16-25-44.bpo-36960.xEK= HXj.rst b/Misc/NEWS.d/next/Documentation/2019-05-18-16-25-44.bpo-36960.xEKHXj= .rst deleted file mode 100644 index 1d4b213367e76..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-18-16-25-44.bpo-36960.xEKHXj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restructured the :mod:`datetime` docs in the interest of making them more -user-friendly and improving readability. Patch by Brad Solomon. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-22-04-30-07.bpo-37004.BRg= xrt.rst b/Misc/NEWS.d/next/Documentation/2019-05-22-04-30-07.bpo-37004.BRgxrt= .rst deleted file mode 100644 index dfc8b7ed74cae..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-22-04-30-07.bpo-37004.BRgxrt.rst +++ /dev/null @@ -1 +0,0 @@ -In the documentation for difflib, a note was added explicitly warning that t= he results of SequenceMatcher's ratio method may depend on the order of the i= nput strings. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-06-04-09-29-00.bpo-36260.WrG= uc-.rst b/Misc/NEWS.d/next/Documentation/2019-06-04-09-29-00.bpo-36260.WrGuc-= .rst deleted file mode 100644 index 9276516a88239..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-06-04-09-29-00.bpo-36260.WrGuc-.rst +++ /dev/null @@ -1 +0,0 @@ -Add decompression pitfalls to zipfile module documentation. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_w= GRc.rst b/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc= .rst deleted file mode 100644 index 7e277f4ec1aed..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-06-17-09-36-46.bpo-34903.r_wGRc.rst +++ /dev/null @@ -1 +0,0 @@ -Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in= some two-digit formats is optional. Patch by Mike Gleen. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0i= oLw.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw= .rst deleted file mode 100644 index 55b136621762d..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-06-00-57-27.bpo-37478.B0ioLw.rst +++ /dev/null @@ -1 +0,0 @@ -Added possible exceptions to the description of os.chdir(). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-02-19-02.bpo-37149.Num= Hn3.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-02-19-02.bpo-37149.NumHn3= .rst deleted file mode 100644 index f9b88dc0bfe0d..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-06-02-19-02.bpo-37149.NumHn3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Replace the dead link to the Tkinter 8.5 reference by John Shipman, New -Mexico Tech, with a link to the archive.org copy. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.Qag= fZ5.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5= .rst deleted file mode 100644 index 605d08c3c0406..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-06-17-19-26.bpo-37487.QagfZ5.rst +++ /dev/null @@ -1 +0,0 @@ -Fix PyList_GetItem index description to include 0. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgA= QHn.rst b/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn= .rst deleted file mode 100644 index 4d158733b0ea0..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-06-17-51-36.bpo-37456.lgAQHn.rst +++ /dev/null @@ -1 +0,0 @@ -Slash ('/') is now part of syntax. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7ti= FR-.rst b/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-= .rst deleted file mode 100644 index 35d7f56f732fe..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-12-15-09-56.bpo-37521.7tiFR-.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix `importlib` examples to insert any newly created modules via -importlib.util.module_from_spec() immediately into sys.modules instead of -after calling loader.exec_module(). - -Thanks to Benjamin Mintz for finding the bug. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-13-12-43-01.bpo-30088.CIc= Bjy.rst b/Misc/NEWS.d/next/Documentation/2019-07-13-12-43-01.bpo-30088.CIcBjy= .rst deleted file mode 100644 index a39fe3fbbcb6e..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-13-12-43-01.bpo-30088.CIcBjy.rst +++ /dev/null @@ -1 +0,0 @@ -Documented that :class:`mailbox.Maildir` constructor doesn't attempt to veri= fy the maildir folder layout correctness. Patch by Sviatoslav Sydorenko. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-07-13-12-58-20.bpo-37284.rP8= WpB.rst b/Misc/NEWS.d/next/Documentation/2019-07-13-12-58-20.bpo-37284.rP8WpB= .rst deleted file mode 100644 index f875791c9a934..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-13-12-58-20.bpo-37284.rP8WpB.rst +++ /dev/null @@ -1 +0,0 @@ -Add a brief note to indicate that any new ``sys.implementation`` required at= tributes must go through the PEP process. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-07-16-14-48-12.bpo-37256.qJT= rBb.rst b/Misc/NEWS.d/next/Documentation/2019-07-16-14-48-12.bpo-37256.qJTrBb= .rst deleted file mode 100644 index 480d7c87ebc4c..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-16-14-48-12.bpo-37256.qJTrBb.rst +++ /dev/null @@ -1 +0,0 @@ -Fix wording of arguments for :class:`Request` in :mod:`urllib.request` diff --git a/Misc/NEWS.d/next/Documentation/2019-07-25-10-30-32.bpo-32910.caL= LAe.rst b/Misc/NEWS.d/next/Documentation/2019-07-25-10-30-32.bpo-32910.caLLAe= .rst deleted file mode 100644 index 60386a196e7ce..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-25-10-30-32.bpo-32910.caLLAe.rst +++ /dev/null @@ -1 +0,0 @@ -Remove implementation-specific behaviour of how venv's Deactivate works. diff --git a/Misc/NEWS.d/next/Documentation/2019-07-31-11-40-06.bpo-37726.h-3= o9a.rst b/Misc/NEWS.d/next/Documentation/2019-07-31-11-40-06.bpo-37726.h-3o9a= .rst deleted file mode 100644 index 195e9755a43c6..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-07-31-11-40-06.bpo-37726.h-3o9a.rst +++ /dev/null @@ -1,2 +0,0 @@ -Stop recommending getopt in the tutorial for command line argument parsing -and promote argparse. diff --git a/Misc/NEWS.d/next/Documentation/2019-08-04-19-20-58.bpo-37759.EHR= F4i.rst b/Misc/NEWS.d/next/Documentation/2019-08-04-19-20-58.bpo-37759.EHRF4i= .rst deleted file mode 100644 index 90fb7213ebdeb..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-04-19-20-58.bpo-37759.EHRF4i.rst +++ /dev/null @@ -1 +0,0 @@ -Beginning edits to Whatsnew 3.8 diff --git a/Misc/NEWS.d/next/Documentation/2019-08-16-20-01-10.bpo-37878.MvA= 6rZ.rst b/Misc/NEWS.d/next/Documentation/2019-08-16-20-01-10.bpo-37878.MvA6rZ= .rst deleted file mode 100644 index 8da4eb9717d89..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-16-20-01-10.bpo-37878.MvA6rZ.rst +++ /dev/null @@ -1 +0,0 @@ -Make :c:func:`PyThreadState_DeleteCurrent` Internal. diff --git a/Misc/NEWS.d/next/Documentation/2019-08-24-12-59-06.bpo-37937.F7f= Hbt.rst b/Misc/NEWS.d/next/Documentation/2019-08-24-12-59-06.bpo-37937.F7fHbt= .rst deleted file mode 100644 index 26cc16a74d1c7..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-24-12-59-06.bpo-37937.F7fHbt.rst +++ /dev/null @@ -1 +0,0 @@ -Mention ``frame.f_trace`` in :func:`sys.settrace` docs. diff --git a/Misc/NEWS.d/next/Documentation/2019-08-27-01-14-59.bpo-12707.Yj3= _7_.rst b/Misc/NEWS.d/next/Documentation/2019-08-27-01-14-59.bpo-12707.Yj3_7_= .rst deleted file mode 100644 index 423e8310d7374..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-27-01-14-59.bpo-12707.Yj3_7_.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate info(), geturl(), getcode() methods in favor of the headers, url, = and status properties, respectively, for HTTPResponse and addinfourl. Also de= precate the code attribute of addinfourl in favor of the status attribute. Pa= tch by Ashwin Ramaswami \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-08-29-10-40-05.bpo-37979.TAU= x_E.rst b/Misc/NEWS.d/next/Documentation/2019-08-29-10-40-05.bpo-37979.TAUx_E= .rst deleted file mode 100644 index d8d70d6137065..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-29-10-40-05.bpo-37979.TAUx_E.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added a link to dateutil.parser.isoparse in the datetime.fromisoformat -documentation. Patch by Paul Ganssle diff --git a/Misc/NEWS.d/next/Documentation/2019-08-29-14-38-01.bpo-37977.pML= -UI.rst b/Misc/NEWS.d/next/Documentation/2019-08-29-14-38-01.bpo-37977.pML-UI= .rst deleted file mode 100644 index cd0fa3c0584a3..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-08-29-14-38-01.bpo-37977.pML-UI.rst +++ /dev/null @@ -1 +0,0 @@ -Warn more strongly and clearly about pickle insecurity diff --git a/Misc/NEWS.d/next/Documentation/2019-09-05-14-47-51.bpo-36797.KN9= Ga5.rst b/Misc/NEWS.d/next/Documentation/2019-09-05-14-47-51.bpo-36797.KN9Ga5= .rst deleted file mode 100644 index 62a3c176b1c7f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-09-05-14-47-51.bpo-36797.KN9Ga5.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a dead link in the distutils API Reference. diff --git a/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw= 0Gd.rst b/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd= .rst deleted file mode 100644 index c668092b41a66..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-09-07-15-55-46.bpo-26868.Raw0Gd.rst +++ /dev/null @@ -1 +0,0 @@ -Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-09-07-19-09-01.bpo-38053.ltt= ibE.rst b/Misc/NEWS.d/next/Documentation/2019-09-07-19-09-01.bpo-38053.lttibE= .rst deleted file mode 100644 index bc0a98721c8f5..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-09-07-19-09-01.bpo-38053.lttibE.rst +++ /dev/null @@ -1 +0,0 @@ -Modernized the plistlib documentation \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-09-27-23-37-41.bpo-38294.go_= jFf.rst b/Misc/NEWS.d/next/Documentation/2019-09-27-23-37-41.bpo-38294.go_jFf= .rst deleted file mode 100644 index 0bde8c868c9ec..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-09-27-23-37-41.bpo-38294.go_jFf.rst +++ /dev/null @@ -1 +0,0 @@ -Add list of no-longer-escaped chars to re.escape documentation \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-10-26-13-19-07.bpo-38592.Y96= BYO.rst b/Misc/NEWS.d/next/Documentation/2019-10-26-13-19-07.bpo-38592.Y96BYO= .rst deleted file mode 100644 index 3752d48a7cb4f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-10-26-13-19-07.bpo-38592.Y96BYO.rst +++ /dev/null @@ -1 +0,0 @@ -Add Brazilian Portuguese to the language switcher at Python Documentation we= bsite. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHh= Tlv.rst b/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv= .rst deleted file mode 100644 index 053e1d294b70f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-11-12-15-31-09.bpo-38778.PHhTlv.rst +++ /dev/null @@ -1 +0,0 @@ -Document the fact that :exc:`RuntimeError` is raised if :meth:`os.fork` is c= alled in a subinterpreter. diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwh= lse.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse= .rst deleted file mode 100644 index 8e0dc9eb4ca2f..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-11-15-09-22-28.bpo-38351.xwhlse.rst +++ /dev/null @@ -1 +0,0 @@ -Modernize :mod:`email` examples from %-formatting to f-strings. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUa= SVL.rst b/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL= .rst deleted file mode 100644 index 49accbc70663a..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-11-15-11-39-13.bpo-38816.vUaSVL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Provides more details about the interaction between :c:func:`fork` and -CPython's runtime, focusing just on the C-API. This includes cautions -about where :c:func:`fork` should and shouldn't be called. diff --git a/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3= Dos.rst b/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos= .rst deleted file mode 100644 index 1e2a45e1113cf..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-11-17-11-54-57.bpo-21767.Qq3Dos.rst +++ /dev/null @@ -1 +0,0 @@ -Explicitly mention abc support in functools.singledispatch diff --git a/Misc/NEWS.d/next/IDLE/2019-03-21-08-35-00.bpo-36390.OdDCGk.rst b= /Misc/NEWS.d/next/IDLE/2019-03-21-08-35-00.bpo-36390.OdDCGk.rst deleted file mode 100644 index 74bbda3402499..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-03-21-08-35-00.bpo-36390.OdDCGk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Gather Format menu functions into format.py. Combine -paragraph.py, rstrip.py, and format methods from editor.py. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst b/= Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst deleted file mode 100644 index 9fc6420774888..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-03-00-39-29.bpo-5680.VCQfOO.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add 'Run... Customized' to the Run menu to run a module with customized -settings. Any 'command line arguments' entered are added to sys.argv. -One can suppress the normal Shell main module restart. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst b= /Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst deleted file mode 100644 index c2b6594cc3506..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make calltip reminder about '/' meaning positional-only less obtrusive by -only adding it when there is room on the first line. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst b= /Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst deleted file mode 100644 index 68d80ae4eaea1..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-04-23-27-33.bpo-37039.FN_fBf.rst +++ /dev/null @@ -1,4 +0,0 @@ -Adjust "Zoom Height" to individual screens by momentarily maximizing the -window on first use with a particular screen. Changing screen settings -may invalidate the saved height. While a window is maximized, -"Zoom Height" has no effect. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst b= /Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst deleted file mode 100644 index 74e48eef89a62..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Properly 'attach' search dialogs to their main window so that they behave -like other dialogs and do not get hidden behind their main window. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst b= /Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst deleted file mode 100644 index 8514bb9292fec..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-10-22-48-50.bpo-26806.Zltkum.rst +++ /dev/null @@ -1,4 +0,0 @@ -To compensate for stack frames added by IDLE and avoid possible problems -with low recursion limits, add 30 to limits in the user code execution -process. Subtract 30 when reporting recursion limits to make this addition -mostly transparent. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-13-01-07-20.bpo-17535.K8i2St.rst b= /Misc/NEWS.d/next/IDLE/2019-06-13-01-07-20.bpo-17535.K8i2St.rst deleted file mode 100644 index 201a413b42a35..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-13-01-07-20.bpo-17535.K8i2St.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add optional line numbers for IDLE editor windows. Windows -open without line numbers unless set otherwise in the General -tab of the configuration dialog.=20 - diff --git a/Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst b= /Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst deleted file mode 100644 index 1321986c5a2c7..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-17-16-35-30.bpo-37321.zVTTGS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Both subprocess connection error messages now refer to the 'Startup failure' -section of the IDLE doc. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst b= /Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst deleted file mode 100644 index edfffbefe884a..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-18-16-40-05.bpo-37325.GssOf1.rst +++ /dev/null @@ -1 +0,0 @@ -Fix tab focus traversal order for help source and custom run dialogs. diff --git a/Misc/NEWS.d/next/IDLE/2019-07-03-22-47-44.bpo-27452.nePPLi.rst b= /Misc/NEWS.d/next/IDLE/2019-07-03-22-47-44.bpo-27452.nePPLi.rst deleted file mode 100644 index ddd37bb865050..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-03-22-47-44.bpo-27452.nePPLi.rst +++ /dev/null @@ -1 +0,0 @@ -Cleanup ``config.py`` by inlining ``RemoveFile`` and simplifying the handlin= g of ``file`` in ``CreateConfigHandlers``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/IDLE/2019-07-11-00-05-31.bpo-37530.AuyCyD.rst b= /Misc/NEWS.d/next/IDLE/2019-07-11-00-05-31.bpo-37530.AuyCyD.rst deleted file mode 100644 index 0b80860b8fc22..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-11-00-05-31.bpo-37530.AuyCyD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Optimize code context to reduce unneeded background activity. -Font and highlight changes now occur along with text changes -instead of after a random delay. diff --git a/Misc/NEWS.d/next/IDLE/2019-07-18-10-11-36.bpo-33610.xYqMLg.rst b= /Misc/NEWS.d/next/IDLE/2019-07-18-10-11-36.bpo-33610.xYqMLg.rst deleted file mode 100644 index 6775b04378b0e..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-18-10-11-36.bpo-33610.xYqMLg.rst +++ /dev/null @@ -1 +0,0 @@ -Fix code context not showing the correct context when first toggled on. diff --git a/Misc/NEWS.d/next/IDLE/2019-07-20-23-33-53.bpo-37627.dQhUNB.rst b= /Misc/NEWS.d/next/IDLE/2019-07-20-23-33-53.bpo-37627.dQhUNB.rst deleted file mode 100644 index d864d07f60ef7..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-20-23-33-53.bpo-37627.dQhUNB.rst +++ /dev/null @@ -1,3 +0,0 @@ -Initialize the Customize Run dialog with the command line arguments -most recently entered before. The user can optionally edit before -submitting them. diff --git a/Misc/NEWS.d/next/IDLE/2019-07-26-17-51-13.bpo-37628.kX4AUF.rst b= /Misc/NEWS.d/next/IDLE/2019-07-26-17-51-13.bpo-37628.kX4AUF.rst deleted file mode 100644 index 60910c47e65bb..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-26-17-51-13.bpo-37628.kX4AUF.rst +++ /dev/null @@ -1 +0,0 @@ -Settings dialog no longer expands with font size. diff --git a/Misc/NEWS.d/next/IDLE/2019-07-27-15-14-20.bpo-37692.TRHGjD.rst b= /Misc/NEWS.d/next/IDLE/2019-07-27-15-14-20.bpo-37692.TRHGjD.rst deleted file mode 100644 index b3beadc1e0264..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-07-27-15-14-20.bpo-37692.TRHGjD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve highlight config sample with example shell interaction and better -labels for shell elements. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-04-15-27-50.bpo-37748.0vf6pg.rst b= /Misc/NEWS.d/next/IDLE/2019-08-04-15-27-50.bpo-37748.0vf6pg.rst deleted file mode 100644 index fc1d6b6bb3572..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-04-15-27-50.bpo-37748.0vf6pg.rst +++ /dev/null @@ -1 +0,0 @@ -Reorder the Run menu. Put the most common choice, Run Module, at the top. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-04-17-10-01.bpo-36419.TJZqOc.rst b= /Misc/NEWS.d/next/IDLE/2019-08-04-17-10-01.bpo-36419.TJZqOc.rst deleted file mode 100644 index 2a5b0bd0e90c2..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-04-17-10-01.bpo-36419.TJZqOc.rst +++ /dev/null @@ -1 +0,0 @@ -Refactor IDLE autocomplete and improve testing. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-14-09-43-15.bpo-37849.-bcYF3.rst b= /Misc/NEWS.d/next/IDLE/2019-08-14-09-43-15.bpo-37849.-bcYF3.rst deleted file mode 100644 index 9f700d9031f14..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-14-09-43-15.bpo-37849.-bcYF3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed completions list appearing too high or low when shown above -the current line. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst b= /Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst deleted file mode 100644 index 24b4142484695..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-21-16-02-49.bpo-37902._R_adE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add mousewheel scrolling for IDLE module, path, and stack browsers. -Patch by George Zhang. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-24-22-00-33.bpo-37929.jb7523.rst b= /Misc/NEWS.d/next/IDLE/2019-08-24-22-00-33.bpo-37929.jb7523.rst deleted file mode 100644 index d627b2de2a7c6..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-24-22-00-33.bpo-37929.jb7523.rst +++ /dev/null @@ -1 +0,0 @@ -IDLE Settings dialog now closes properly when there is no shell window. diff --git a/Misc/NEWS.d/next/IDLE/2019-08-26-00-41-53.bpo-37824.YY5jAI.rst b= /Misc/NEWS.d/next/IDLE/2019-08-26-00-41-53.bpo-37824.YY5jAI.rst deleted file mode 100644 index 1a1e8a59816ae..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-08-26-00-41-53.bpo-37824.YY5jAI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Properly handle user input warnings in IDLE shell. Cease turning -SyntaxWarnings into SyntaxErrors. diff --git a/Misc/NEWS.d/next/IDLE/2019-09-01-10-22-55.bpo-35771.tdbmbP.rst b= /Misc/NEWS.d/next/IDLE/2019-09-01-10-22-55.bpo-35771.tdbmbP.rst deleted file mode 100644 index b96e53f5a5dfd..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-09-01-10-22-55.bpo-35771.tdbmbP.rst +++ /dev/null @@ -1,2 +0,0 @@ -To avoid occasional spurious test_idle failures on slower machines,=20 -increase the ``hover_delay`` in test_tooltip. diff --git a/Misc/NEWS.d/next/IDLE/2019-09-05-23-12-13.bpo-38041.nxmGGK.rst b= /Misc/NEWS.d/next/IDLE/2019-09-05-23-12-13.bpo-38041.nxmGGK.rst deleted file mode 100644 index 0aa254e8ca70f..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-09-05-23-12-13.bpo-38041.nxmGGK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Shell restart lines now fill the window width, always start with '=3D', -and avoid wrapping unnecessarily. The line will still wrap if the -included file name is long relative to the width. diff --git a/Misc/NEWS.d/next/IDLE/2019-09-09-22-08-36.bpo-38077.Mzpfe2.rst b= /Misc/NEWS.d/next/IDLE/2019-09-09-22-08-36.bpo-38077.Mzpfe2.rst deleted file mode 100644 index ba1fd55defaa2..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-09-09-22-08-36.bpo-38077.Mzpfe2.rst +++ /dev/null @@ -1,2 +0,0 @@ -IDLE no longer adds 'argv' to the user namespace when initializing it. This -bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. diff --git a/Misc/NEWS.d/next/IDLE/2019-09-16-15-04-29.bpo-38183.eudCN1.rst b= /Misc/NEWS.d/next/IDLE/2019-09-16-15-04-29.bpo-38183.eudCN1.rst deleted file mode 100644 index e545f49bc836e..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-09-16-15-04-29.bpo-38183.eudCN1.rst +++ /dev/null @@ -1,3 +0,0 @@ -To avoid problems, test_idle ignores the user config directory. -It no longer tries to create or access .idlerc or any files within. -Users must run IDLE to discover problems with saving settings. diff --git a/Misc/NEWS.d/next/IDLE/2019-09-17-01-28-56.bpo-35379.yAECDr.rst b= /Misc/NEWS.d/next/IDLE/2019-09-17-01-28-56.bpo-35379.yAECDr.rst deleted file mode 100644 index 98d41674b65d5..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-09-17-01-28-56.bpo-35379.yAECDr.rst +++ /dev/null @@ -1,3 +0,0 @@ -When exiting IDLE, catch any AttributeError. One happens when -EditorWindow.close is called twice. Printing a traceback, when IDLE is run -from a terminal, is useless and annoying. diff --git a/Misc/NEWS.d/next/IDLE/2019-10-04-18-03-09.bpo-36698.BKcmom.rst b= /Misc/NEWS.d/next/IDLE/2019-10-04-18-03-09.bpo-36698.BKcmom.rst deleted file mode 100644 index 5aaa3c92646a1..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-10-04-18-03-09.bpo-36698.BKcmom.rst +++ /dev/null @@ -1,3 +0,0 @@ -IDLE no longer fails when write non-encodable characters to stderr. It now -escapes them with a backslash, as the regular Python interpreter. Added the -``errors`` field to the standard streams. diff --git a/Misc/NEWS.d/next/IDLE/2019-10-26-18-16-24.bpo-38598.6kH9FY.rst b= /Misc/NEWS.d/next/IDLE/2019-10-26-18-16-24.bpo-38598.6kH9FY.rst deleted file mode 100644 index 5d04e4a79b622..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-10-26-18-16-24.bpo-38598.6kH9FY.rst +++ /dev/null @@ -1 +0,0 @@ -Do not try to compile IDLE shell or output windows diff --git a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst b/= Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst deleted file mode 100644 index 759b35b77fb8d..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-10-28-04-48-03.bpo-4630.upgjiV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add an option to toggle IDLE's cursor blink for shell, editor, and output -windows. See Settings, General, Window Preferences, Cursor Blink. -Patch by Zachary Spytz. diff --git a/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst b= /Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst deleted file mode 100644 index fd0a2a3682100..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-11-09-23-55-59.bpo-26353.duYZiF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Stop adding newline when saving an IDLE shell window. - diff --git a/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst= b/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst deleted file mode 100644 index 3b060052fd350..0000000000000 --- a/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed non-deterministic behavior related to mimetypes extension mapping and -module reinitialization. diff --git a/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rs= t b/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst deleted file mode 100644 index 77746c0ce630f..0000000000000 --- a/Misc/NEWS.d/next/Library/2017-12-26-14-32-23.bpo-27657.6BhyVK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix urllib.parse.urlparse() with numeric paths. A string like "path:80" is -no longer parsed as a path but as a scheme ("path") and a path ("80"). diff --git a/Misc/NEWS.d/next/Library/2018-02-13-12-25-43.bpo-32820.0stF0u.rs= t b/Misc/NEWS.d/next/Library/2018-02-13-12-25-43.bpo-32820.0stF0u.rst deleted file mode 100644 index dd5bd269cbf78..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-02-13-12-25-43.bpo-32820.0stF0u.rst +++ /dev/null @@ -1,4 +0,0 @@ -Added __format__ to IPv4 and IPv6 classes. Always outputs a fully zero- -padded string. Supports b/x/n modifiers (bin/hex/native format). Native -format for IPv4 is bin, native format for IPv6 is hex. Also supports '#' and -'_' modifiers. diff --git a/Misc/NEWS.d/next/Library/2018-02-13-17-58-30.bpo-32689.a-3SnH.rs= t b/Misc/NEWS.d/next/Library/2018-02-13-17-58-30.bpo-32689.a-3SnH.rst deleted file mode 100644 index d435351a3a75e..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-02-13-17-58-30.bpo-32689.a-3SnH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update :func:`shutil.move` function to allow for Path objects to be used as -source argument. Patch by Emily Morehouse and Maxwell "5.13b" McKinnon. diff --git a/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rs= t b/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst deleted file mode 100644 index f95a73fb57ed4..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-24-13-18-48.bpo-33348.XaJDei.rst +++ /dev/null @@ -1,2 +0,0 @@ -lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or -[])``. diff --git a/Misc/NEWS.d/next/Library/2018-06-17-21-02-25.bpo-32498.La3TZz.rs= t b/Misc/NEWS.d/next/Library/2018-06-17-21-02-25.bpo-32498.La3TZz.rst deleted file mode 100644 index 9df9e65e55b3e..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-06-17-21-02-25.bpo-32498.La3TZz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Made :func:`urllib.parse.unquote()` accept bytes in addition to strings. -Patch by Stein Karlsen. diff --git a/Misc/NEWS.d/next/Library/2018-07-14-13-48-56.bpo-30618.T5AUF6.rs= t b/Misc/NEWS.d/next/Library/2018-07-14-13-48-56.bpo-30618.T5AUF6.rst deleted file mode 100644 index 35bdb4ef25647..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-07-14-13-48-56.bpo-30618.T5AUF6.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`~pathlib.Path.readlink`. Patch by Girts Folkmanis. diff --git a/Misc/NEWS.d/next/Library/2018-08-04-12-26-11.bpo-28009.4JcHZb.rs= t b/Misc/NEWS.d/next/Library/2018-08-04-12-26-11.bpo-28009.4JcHZb.rst deleted file mode 100644 index 40f638234a458..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-04-12-26-11.bpo-28009.4JcHZb.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix uuid.getnode() on platforms with '.' as MAC Addr delimiter as well -fix for MAC Addr format that omits a leading 0 in MAC Addr values. -Currently, AIX is the only know platform with these settings. -Patch by Michael Felt. diff --git a/Misc/NEWS.d/next/Library/2018-08-27-15-44-50.bpo-34519.cPlH1h.rs= t b/Misc/NEWS.d/next/Library/2018-08-27-15-44-50.bpo-34519.cPlH1h.rst deleted file mode 100644 index e17e2dc0fdcce..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-27-15-44-50.bpo-34519.cPlH1h.rst +++ /dev/null @@ -1 +0,0 @@ -Add additional aliases for HP Roman 8. Patch by Michael Osipov. diff --git a/Misc/NEWS.d/next/Library/2018-09-21-13-23-29.bpo-34749.B0k819.rs= t b/Misc/NEWS.d/next/Library/2018-09-21-13-23-29.bpo-34749.B0k819.rst deleted file mode 100644 index 5a5e5b492c0b8..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-09-21-13-23-29.bpo-34749.B0k819.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`binascii.a2b_base64` is now up to 2 times faster. Patch by Sergey -Fedoseev. diff --git a/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rs= t b/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst deleted file mode 100644 index f99bf5b39f951..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-09-23-03-18-52.bpo-34775.vHeuHk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Division handling of PurePath now returns NotImplemented instead of raising -a TypeError when passed something other than an instance of str or PurePath. -Patch by Roger Aiudi. diff --git a/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rs= t b/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst deleted file mode 100644 index 483906613801c..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst +++ /dev/null @@ -1 +0,0 @@ -Distutils won't check for rpmbuild in specified paths only. diff --git a/Misc/NEWS.d/next/Library/2018-11-19-10-23-58.bpo-25988.6o7gGK.rs= t b/Misc/NEWS.d/next/Library/2018-11-19-10-23-58.bpo-25988.6o7gGK.rst deleted file mode 100644 index 21d25e8d74ced..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-11-19-10-23-58.bpo-25988.6o7gGK.rst +++ /dev/null @@ -1,2 +0,0 @@ -The abstract base classes in :mod:`collections.abc` no longer are exposed in -the regular :mod:`collections` module. diff --git a/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rs= t b/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst deleted file mode 100644 index 726329ad0d65a..0000000000000 --- a/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no -`Content-Length` header. diff --git a/Misc/NEWS.d/next/Library/2019-01-09-16-18-52.bpo-8538.PfVZia.rst= b/Misc/NEWS.d/next/Library/2019-01-09-16-18-52.bpo-8538.PfVZia.rst deleted file mode 100644 index 94249ab1e4346..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-09-16-18-52.bpo-8538.PfVZia.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add support for boolean actions like ``--foo`` and ``--no-foo`` to argparse. -Patch contributed by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rs= t b/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst deleted file mode 100644 index 10684fdbde2f1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-22-09-23-20.bpo-35168.UGv2yW.rst +++ /dev/null @@ -1 +0,0 @@ -:attr:`shlex.shlex.punctuation_chars` is now a read-only property. diff --git a/Misc/NEWS.d/next/Library/2019-01-25-17-12-17.bpo-35800.MCGJdQ.rs= t b/Misc/NEWS.d/next/Library/2019-01-25-17-12-17.bpo-35800.MCGJdQ.rst deleted file mode 100644 index 27e8d0bb3a097..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-25-17-12-17.bpo-35800.MCGJdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate ``smtpd.MailmanProxy`` ready for future removal. diff --git a/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rs= t b/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst deleted file mode 100644 index 16708aa5ee545..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-02-03-19-13-08.bpo-32627.b68f64.rst +++ /dev/null @@ -1 +0,0 @@ -Fix compile error when ``_uuid`` headers conflicting included. diff --git a/Misc/NEWS.d/next/Library/2019-02-19-17-32-45.bpo-36046.fX9OPj.rs= t b/Misc/NEWS.d/next/Library/2019-02-19-17-32-45.bpo-36046.fX9OPj.rst deleted file mode 100644 index 5e809d6a6032c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-02-19-17-32-45.bpo-36046.fX9OPj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added ``user``, ``group`` and ``extra_groups`` parameters to the -subprocess.Popen constructor. Patch by Patrick McLean. diff --git a/Misc/NEWS.d/next/Library/2019-03-09-16-04-12.bpo-36250.tSK4N1.rs= t b/Misc/NEWS.d/next/Library/2019-03-09-16-04-12.bpo-36250.tSK4N1.rst deleted file mode 100644 index 8d9fbcbb1cba5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-09-16-04-12.bpo-36250.tSK4N1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ignore ``ValueError`` from ``signal`` with ``interaction`` in non-main -thread. diff --git a/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rs= t b/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst deleted file mode 100644 index fe01b5915d5db..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-21-19-23-46.bpo-36302.Yc591g.rst +++ /dev/null @@ -1,2 +0,0 @@ -distutils sorts source file lists so that Extension .so files -build more reproducibly by default diff --git a/Misc/NEWS.d/next/Library/2019-03-23-16-42-46.bpo-36409.ZYVKao.rs= t b/Misc/NEWS.d/next/Library/2019-03-23-16-42-46.bpo-36409.ZYVKao.rst deleted file mode 100644 index e516d3190f811..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-23-16-42-46.bpo-36409.ZYVKao.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the old plistlib API deprecated in Python 3.4 \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rs= t b/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst deleted file mode 100644 index 1153de872bc72..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-06-20-08-12.bpo-36543.RPjmUz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Removed methods Element.getchildren(), Element.getiterator() and -ElementTree.getiterator() and the xml.etree.cElementTree module. diff --git a/Misc/NEWS.d/next/Library/2019-04-08-13-00-13.bpo-36564._n67m_.rs= t b/Misc/NEWS.d/next/Library/2019-04-08-13-00-13.bpo-36564._n67m_.rst deleted file mode 100644 index ddd17aec1dd86..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-08-13-00-13.bpo-36564._n67m_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix infinite loop in email header folding logic that would be triggered when -an email policy's max_line_length is not long enough to include the required -markup and any values in the message. Patch by Paul Ganssle diff --git a/Misc/NEWS.d/next/Library/2019-04-28-10-34-19.bpo-32424.eqNPhM.rs= t b/Misc/NEWS.d/next/Library/2019-04-28-10-34-19.bpo-32424.eqNPhM.rst deleted file mode 100644 index a60d68bf2de33..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-28-10-34-19.bpo-32424.eqNPhM.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate xml.etree.ElementTree.Element.copy() in favor of copy.copy(). - -Patch by Gordon P. Hemsley diff --git a/Misc/NEWS.d/next/Library/2019-05-07-17-42-36.bpo-36582.L_dxR6.rs= t b/Misc/NEWS.d/next/Library/2019-05-07-17-42-36.bpo-36582.L_dxR6.rst deleted file mode 100644 index 34f16fcde879c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-17-42-36.bpo-36582.L_dxR6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``UserString.encode()`` to correctly return ``bytes`` rather than a ``Us= erString`` instance. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-07-19-25-55.bpo-31783.lgLo69.rs= t b/Misc/NEWS.d/next/Library/2019-05-07-19-25-55.bpo-31783.lgLo69.rst deleted file mode 100644 index a261e59ccfecd..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-19-25-55.bpo-31783.lgLo69.rst +++ /dev/null @@ -1 +0,0 @@ -Fix race condition in ThreadPoolExecutor when worker threads are created dur= ing interpreter shutdown. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rs= t b/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst deleted file mode 100644 index e823f1d469cca..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst +++ /dev/null @@ -1,2 +0,0 @@ -posix.getgrouplist() now works correctly when the user belongs to -NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. diff --git a/Misc/NEWS.d/next/Library/2019-05-12-12-58-37.bpo-36871.6xiEHZ.rs= t b/Misc/NEWS.d/next/Library/2019-05-12-12-58-37.bpo-36871.6xiEHZ.rst deleted file mode 100644 index 218795f203bee..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-12-12-58-37.bpo-36871.6xiEHZ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Ensure method signature is used instead of constructor signature of a class -while asserting mock object against method calls. Patch by Karthikeyan -Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rs= t b/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst deleted file mode 100644 index 2d8c8b3222d09..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add parser for Message-ID header and add it to default HeaderRegistry. This -should prevent folding of Message-ID using RFC 2048 encoded words. diff --git a/Misc/NEWS.d/next/Library/2019-05-17-16-50-02.bpo-31904.4a5ggm.rs= t b/Misc/NEWS.d/next/Library/2019-05-17-16-50-02.bpo-31904.4a5ggm.rst deleted file mode 100644 index eb7163b6a7d79..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-16-50-02.bpo-31904.4a5ggm.rst +++ /dev/null @@ -1 +0,0 @@ -Port test_datetime to VxWorks: skip zoneinfo tests on VxWorks diff --git a/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rs= t b/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst deleted file mode 100644 index dd0dd7f72c0a3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst +++ /dev/null @@ -1,4 +0,0 @@ -Email headers containing RFC2047 encoded words are parsed despite the missing -whitespace, and a defect registered. Also missing trailing whitespace after -encoded words is now registered as a defect. - diff --git a/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rs= t b/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst deleted file mode 100644 index dc71dae69246d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-14-17-29.bpo-26185.pQW4mI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by Micka=C3=ABl -Schoentgen. diff --git a/Misc/NEWS.d/next/Library/2019-05-22-04-52-35.bpo-25068.vR_rC-.rs= t b/Misc/NEWS.d/next/Library/2019-05-22-04-52-35.bpo-25068.vR_rC-.rst deleted file mode 100644 index 89de83bce0290..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-22-04-52-35.bpo-25068.vR_rC-.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`urllib.request.ProxyHandler` now lowercases the keys of the passed -dictionary. diff --git a/Misc/NEWS.d/next/Library/2019-05-26-16-34-53.bpo-31163.21A802.rs= t b/Misc/NEWS.d/next/Library/2019-05-26-16-34-53.bpo-31163.21A802.rst deleted file mode 100644 index 6ec074612141c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-26-16-34-53.bpo-31163.21A802.rst +++ /dev/null @@ -1,2 +0,0 @@ -pathlib.Path instance's rename and replace methods now return the new Path -instance. diff --git a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rs= t b/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst deleted file mode 100644 index 019321d6f1d72..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a bug in email parsing where a message with invalid bytes in -content-transfer-encoding of a multipart message can cause an AttributeError. -Patch by Andrew Donnellan. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rs= t b/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst deleted file mode 100644 index 8171bfe9e2df1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst +++ /dev/null @@ -1 +0,0 @@ -Lengthy email headers with UTF-8 characters are now properly encoded when th= ey are folded. Patch by Jeffrey Kintscher. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rs= t b/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst deleted file mode 100644 index c492e1de6d5c4..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support running asyncio subprocesses when execution event loop in a thread -on UNIX. diff --git a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rs= t b/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst deleted file mode 100755 index 68c469810a37b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-30-15-51-42.bpo-28724.34TrS8.rst +++ /dev/null @@ -1,2 +0,0 @@ -The socket module now has the :func:`socket.send_fds` and :func:`socket.recv= .fds` methods. -Contributed by Joannah Nanjekye, Shinya Okano and Victor Stinner. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst deleted file mode 100644 index c5be46e1e5d3f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst +++ /dev/null @@ -1 +0,0 @@ -`argparse._ActionsContainer.add_argument` now throws error, if someone accid= entally pass FileType class object instead of instance of FileType as `type` = argument \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst deleted file mode 100644 index 66c388e1d6ee1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``Enum._convert`` method, deprecated in 3.8. diff --git a/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst deleted file mode 100644 index 4a5ec4122f943..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst +++ /dev/null @@ -1 +0,0 @@ -Speed-up statistics.fmean() by switching from a function to a generator. diff --git a/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rs= t b/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst deleted file mode 100644 index b46bc44506f4a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst +++ /dev/null @@ -1 +0,0 @@ -Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. diff --git a/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rs= t b/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst deleted file mode 100644 index 5430a57ef54c5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst +++ /dev/null @@ -1 +0,0 @@ -Converted _collections._count_elements to use the Argument Clinic. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rs= t b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst deleted file mode 100644 index 77b872319a919..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst +++ /dev/null @@ -1,2 +0,0 @@ -For math.perm(n, k), let k default to n, giving the same result as -factorial. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rs= t b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst deleted file mode 100644 index 500ef54fd6150..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Give math.perm() a one argument form that means the same as -math.factorial(). diff --git a/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rs= t b/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst deleted file mode 100644 index e996f97ecddd0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst +++ /dev/null @@ -1 +0,0 @@ -The exception message for ``inspect.getfile()`` now correctly reports the pa= ssed class rather than the builtins module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rs= t b/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst deleted file mode 100644 index 1b5fc37025212..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix an unintended ValueError from :func:`subprocess.run` when checking for -conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` -args when they were explicitly provided but with `None` values within a -passed in `**kwargs` dict rather than as passed directly by name. Patch -contributed by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-06-08-23-26-58.bpo-12144.Z7mz-q.rs= t b/Misc/NEWS.d/next/Library/2019-06-08-23-26-58.bpo-12144.Z7mz-q.rst deleted file mode 100644 index ee802f81477ec..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-08-23-26-58.bpo-12144.Z7mz-q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure cookies with ``expires`` attribute are handled in -:meth:`CookieJar.make_cookies`. diff --git a/Misc/NEWS.d/next/Library/2019-06-09-17-22-33.bpo-37111.2I0z2k.rs= t b/Misc/NEWS.d/next/Library/2019-06-09-17-22-33.bpo-37111.2I0z2k.rst deleted file mode 100644 index 39821ed1419d6..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-09-17-22-33.bpo-37111.2I0z2k.rst +++ /dev/null @@ -1 +0,0 @@ -Added ``encoding`` and ``errors`` keyword parameters to ``logging.basicConfi= g``. diff --git a/Misc/NEWS.d/next/Library/2019-06-09-22-25-03.bpo-37206.2WBg4q.rs= t b/Misc/NEWS.d/next/Library/2019-06-09-22-25-03.bpo-37206.2WBg4q.rst deleted file mode 100644 index 2c6c6821e639e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-09-22-25-03.bpo-37206.2WBg4q.rst +++ /dev/null @@ -1,2 +0,0 @@ -Default values which cannot be represented as Python objects no longer -improperly represented as ``None`` in function signatures. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst deleted file mode 100644 index 3bc537e40ff69..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix a race condition at Python shutdown when waiting for threads. Wait until -the Python thread state of all non-daemon threads get deleted (join all -non-daemon threads), rather than just wait until non-daemon Python threads -complete. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst deleted file mode 100644 index 295ddebb2a401..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` -attribute fails to better mimick :class:`_io.IOBase` finalizer. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst deleted file mode 100644 index 337c8e2668c49..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if -internal tasks weak set is changed by another thread during iteration. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst deleted file mode 100644 index 6dd49998cb4c2..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst +++ /dev/null @@ -1 +0,0 @@ -Change the format of feature_version to be a (major, minor) tuple. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rs= t b/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst deleted file mode 100644 index 5271a495624d6..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :meth:`RobotFileParser.crawl_delay` and -:meth:`RobotFileParser.request_rate` to return ``None`` rather than -raise :exc:`AttributeError` when no relevant rule is defined in the -robots.txt file. Patch by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-06-12-08-56-22.bpo-21872.V9QGGN.rs= t b/Misc/NEWS.d/next/Library/2019-06-12-08-56-22.bpo-21872.V9QGGN.rst deleted file mode 100644 index 90df756f9a81b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-12-08-56-22.bpo-21872.V9QGGN.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :mod:`lzma`: module decompresses data incompletely. When decompressing a -FORMAT_ALONE format file, and it doesn't have the end marker, sometimes the -last one to dozens bytes can't be output. Patch by Ma Lin. diff --git a/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rs= t b/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst deleted file mode 100644 index 58fc66b59059d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst +++ /dev/null @@ -1 +0,0 @@ -Allow pure Python implementation of :mod:`pickle` to work even when the C :m= od:`_pickle` module is unavailable. diff --git a/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rs= t b/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst deleted file mode 100644 index f41918185213c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst +++ /dev/null @@ -1,4 +0,0 @@ -In a subinterpreter, spawning a daemon thread now raises an exception. Daemon -threads were never supported in subinterpreters. Previously, the subinterpre= ter -finalization crashed with a Pyton fatal error if a daemon thread was still -running. diff --git a/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst deleted file mode 100644 index efd1f55c0135b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters -on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst deleted file mode 100644 index d740b9b62b080..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix asyncio sendfile support when sendfile sends extra data in fallback -mode. diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rs= t b/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst deleted file mode 100644 index 7cdc56a72ce4f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst +++ /dev/null @@ -1 +0,0 @@ -Use threadpool for reading from file for sendfile fallback mode. diff --git a/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rs= t b/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst deleted file mode 100644 index ded1570b308fb..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-15-14-39-50.bpo-33972.XxnNPw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Email with single part but content-type set to ``multipart/*`` doesn't raise -AttributeError anymore. diff --git a/Misc/NEWS.d/next/Library/2019-06-17-10-03-52.bpo-37312.qKvBfF.rs= t b/Misc/NEWS.d/next/Library/2019-06-17-10-03-52.bpo-37312.qKvBfF.rst deleted file mode 100644 index eaaa0daf02b89..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-17-10-03-52.bpo-37312.qKvBfF.rst +++ /dev/null @@ -1,2 +0,0 @@ -``_dummy_thread`` and ``dummy_threading`` modules have been removed. These -modules were deprecated since Python 3.7 which requires threading support. diff --git a/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rs= t b/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst deleted file mode 100644 index fd5981989b7da..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecated accepting floats with integral value (like ``5.0``) in -:func:`math.factorial`. diff --git a/Misc/NEWS.d/next/Library/2019-06-17-22-10-37.bpo-37320.ffieYa.rs= t b/Misc/NEWS.d/next/Library/2019-06-17-22-10-37.bpo-37320.ffieYa.rst deleted file mode 100644 index bc5745261cfab..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-17-22-10-37.bpo-37320.ffieYa.rst +++ /dev/null @@ -1,3 +0,0 @@ -``aifc.openfp()`` alias to ``aifc.open()``, ``sunau.openfp()`` alias to -``sunau.open()``, and ``wave.openfp()`` alias to ``wave.open()`` have been -removed. They were deprecated since Python 3.7. diff --git a/Misc/NEWS.d/next/Library/2019-06-18-13-59-55.bpo-37305.fGzWlP.rs= t b/Misc/NEWS.d/next/Library/2019-06-18-13-59-55.bpo-37305.fGzWlP.rst deleted file mode 100644 index 5bd2cd4d30afa..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-18-13-59-55.bpo-37305.fGzWlP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add .webmanifest -> application/manifest+json to list of recognized file typ= es -and content type headers diff --git a/Misc/NEWS.d/next/Library/2019-06-18-15-31-33.bpo-37328.2PW1-l.rs= t b/Misc/NEWS.d/next/Library/2019-06-18-15-31-33.bpo-37328.2PW1-l.rst deleted file mode 100644 index d91ab1b295d37..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-18-15-31-33.bpo-37328.2PW1-l.rst +++ /dev/null @@ -1,2 +0,0 @@ -``HTMLParser.unescape`` is removed. It was undocumented and deprecated -since Python 3.4. diff --git a/Misc/NEWS.d/next/Library/2019-06-18-16-29-31.bpo-37085.GeYaD6.rs= t b/Misc/NEWS.d/next/Library/2019-06-18-16-29-31.bpo-37085.GeYaD6.rst deleted file mode 100644 index e8db521d7abad..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-18-16-29-31.bpo-37085.GeYaD6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add the optional Linux SocketCAN Broadcast Manager constants, used as flags -to configure the BCM behaviour, in the socket module. Patch by Karl Ding. diff --git a/Misc/NEWS.d/next/Library/2019-06-19-10-35-53.bpo-37163.9pPg2F.rs= t b/Misc/NEWS.d/next/Library/2019-06-19-10-35-53.bpo-37163.9pPg2F.rst deleted file mode 100644 index 07182e7675d11..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-19-10-35-53.bpo-37163.9pPg2F.rst +++ /dev/null @@ -1 +0,0 @@ -The *obj* argument of :func:`dataclasses.replace` is positional-only now. diff --git a/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rs= t b/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst deleted file mode 100644 index 1e61f5e0b3dbe..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-20-14-23-48.bpo-37347.Gf9yYI.rst +++ /dev/null @@ -1,6 +0,0 @@ -:meth:`sqlite3.Connection.create_aggregate`, -:meth:`sqlite3.Connection.create_function`, -:meth:`sqlite3.Connection.set_authorizer`, -:meth:`sqlite3.Connection.set_progress_handler`=20 -:meth:`sqlite3.Connection.set_trace_callback`=20 -methods lead to segfaults if some of these methods are called twice with an = equal object but not the same. Now callbacks are stored more carefully. Patch= by Aleksandr Balezin. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-21-14-54-02.bpo-37358.RsASpn.rs= t b/Misc/NEWS.d/next/Library/2019-06-21-14-54-02.bpo-37358.RsASpn.rst deleted file mode 100644 index bc37631020f66..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-21-14-54-02.bpo-37358.RsASpn.rst +++ /dev/null @@ -1 +0,0 @@ -Optimized ``functools.partial`` by using vectorcall. diff --git a/Misc/NEWS.d/next/Library/2019-06-22-08-51-44.bpo-37345.o8XABX.rs= t b/Misc/NEWS.d/next/Library/2019-06-22-08-51-44.bpo-37345.o8XABX.rst deleted file mode 100644 index f43fd00a635e7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-22-08-51-44.bpo-37345.o8XABX.rst +++ /dev/null @@ -1,6 +0,0 @@ -Add formal support for UDPLITE sockets. Support was present before, but it -is now easier to detect support with ``hasattr(socket, 'IPPROTO_UDPLITE')`` -and there are constants defined for each of the values needed: -:py:obj:`socket.IPPROTO_UDPLITE`, :py:obj:`UDPLITE_SEND_CSCOV`, and -:py:obj:`UDPLITE_RECV_CSCOV`. -Patch by Gabe Appleton. diff --git a/Misc/NEWS.d/next/Library/2019-06-22-12-30-00.bpo-37372.kIKqZ6.rs= t b/Misc/NEWS.d/next/Library/2019-06-22-12-30-00.bpo-37372.kIKqZ6.rst deleted file mode 100644 index b958d8fed40a8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-22-12-30-00.bpo-37372.kIKqZ6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix error unpickling datetime.time objects from Python 2 with seconds>=3D24. -Patch by Justin Blanchard. diff --git a/Misc/NEWS.d/next/Library/2019-06-22-22-00-35.bpo-37212.Zhv-tq.rs= t b/Misc/NEWS.d/next/Library/2019-06-22-22-00-35.bpo-37212.Zhv-tq.rst deleted file mode 100644 index 520a0229aa9d0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-22-22-00-35.bpo-37212.Zhv-tq.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`unittest.mock.call` now preserves the order of keyword arguments in -repr output. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rs= t b/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst deleted file mode 100644 index c5852f6142150..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-23-12-46-10.bpo-26967.xEuem1.rst +++ /dev/null @@ -1,3 +0,0 @@ -An :class:`~argparse.ArgumentParser` with ``allow_abbrev=3DFalse`` no longer -disables grouping of short flags, such as ``-vv``, but only disables -abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds. diff --git a/Misc/NEWS.d/next/Library/2019-06-24-11-26-34.bpo-37376.SwSUQ4.rs= t b/Misc/NEWS.d/next/Library/2019-06-24-11-26-34.bpo-37376.SwSUQ4.rst deleted file mode 100644 index f47d8130f6ec7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-24-11-26-34.bpo-37376.SwSUQ4.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`pprint` now has support for :class:`types.SimpleNamespace`. Patch by C= arl -Bordum Hansen. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst deleted file mode 100644 index 8d0d2fa311bca..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-02-10-00.bpo-37394.srZ1zx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug that was causing the :mod:`queue` module to fail if the -accelerator module was not available. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst deleted file mode 100644 index f6829fb1727e7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-05-07-48.bpo-36546.RUcxaK.rst +++ /dev/null @@ -1,4 +0,0 @@ -The *dist* argument for statistics.quantiles() is now positional only. The -current name doesn't reflect that the argument can be either a dataset or a -distribution. Marking the parameter as positional avoids confusion and -makes it possible to change the name later. diff --git a/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rs= t b/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst deleted file mode 100644 index b8fac46736867..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-25-19-27-25.bpo-29412.n4Zqdh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix IndexError in parsing a header value ending unexpectedly. Patch by Abhil= ash -Raj. diff --git a/Misc/NEWS.d/next/Library/2019-06-26-03-00-06.bpo-37406.uovkpq.rs= t b/Misc/NEWS.d/next/Library/2019-06-26-03-00-06.bpo-37406.uovkpq.rst deleted file mode 100644 index 9a195ffae218e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-26-03-00-06.bpo-37406.uovkpq.rst +++ /dev/null @@ -1,3 +0,0 @@ -The sqlite3 module now raises TypeError, rather than ValueError, if -operation argument type is not str: execute(), executemany() and calling a -connection. diff --git a/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rs= t b/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst deleted file mode 100644 index 3ce4102129f05..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-26-16-28-59.bpo-37412.lx0VjC.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, -rather than the ANSI code page: see :pep:`529` for the rationale. The functi= on -is no longer deprecated on Windows. diff --git a/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rs= t b/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst deleted file mode 100644 index dea1a29250144..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-26-22-25-05.bpo-37420.CxFJ09.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`os.sched_setaffinity` now correctly handles errors that arise during = iteration over its ``mask`` argument. -Patch by Brandt Bucher. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rs= t b/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst deleted file mode 100644 index 2cdce6b24dc6b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-27-13-27-02.bpo-37428._wcwUd.rst +++ /dev/null @@ -1,4 +0,0 @@ -SSLContext.post_handshake_auth =3D True no longer sets -SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the -option is documented as ignored for clients, OpenSSL implicitly enables cert -chain validation when the flag is set. diff --git a/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rs= t b/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst deleted file mode 100644 index 80719ee152d7a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-27-20-33-50.bpo-37437.du39_A.rst +++ /dev/null @@ -1 +0,0 @@ -Update vendorized expat version to 2.2.7. diff --git a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rs= t b/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst deleted file mode 100644 index b336e061e15e8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-28-16-40-17.bpo-37440.t3wX-N.rst +++ /dev/null @@ -1,2 +0,0 @@ -http.client now enables TLS 1.3 post-handshake authentication for default -context or if a cert_file is passed to HTTPSConnection. diff --git a/Misc/NEWS.d/next/Library/2019-07-02-12-43-57.bpo-37479.O53a5S.rs= t b/Misc/NEWS.d/next/Library/2019-07-02-12-43-57.bpo-37479.O53a5S.rst deleted file mode 100644 index cf23155c33958..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-02-12-43-57.bpo-37479.O53a5S.rst +++ /dev/null @@ -1,2 +0,0 @@ -When `Enum.__str__` is overridden in a derived class, the override will be -used by `Enum.__format__` regardless of whether mixin classes are present. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-07-02-13-08-30.bpo-37481.hd5k09.rs= t b/Misc/NEWS.d/next/Library/2019-07-02-13-08-30.bpo-37481.hd5k09.rst deleted file mode 100644 index a3faecdd9151e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-02-13-08-30.bpo-37481.hd5k09.rst +++ /dev/null @@ -1,2 +0,0 @@ -The distutils ``bdist_wininst`` command is deprecated in Python 3.8, use -``bdist_wheel`` (wheel packages) instead. diff --git a/Misc/NEWS.d/next/Library/2019-07-03-12-47-52.bpo-37421.gR5hC8.rs= t b/Misc/NEWS.d/next/Library/2019-07-03-12-47-52.bpo-37421.gR5hC8.rst deleted file mode 100644 index 450d76f072890..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-03-12-47-52.bpo-37421.gR5hC8.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear also the -'tempdir' configuration of the current process, so next call to -``get_temp_dir()`` will create a new temporary directory, rather than -reusing the removed temporary directory. diff --git a/Misc/NEWS.d/next/Library/2019-07-04-13-00-20.bpo-37424.0i1MR-.rs= t b/Misc/NEWS.d/next/Library/2019-07-04-13-00-20.bpo-37424.0i1MR-.rst deleted file mode 100644 index b98a17e241e07..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-04-13-00-20.bpo-37424.0i1MR-.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixes a possible hang when using a timeout on `subprocess.run()` while -capturing output. If the child process spawned its own children or -otherwise connected its stdout or stderr handles with another process, we -could hang after the timeout was reached and our child was killed when -attempting to read final output from the pipes. diff --git a/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rs= t b/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst deleted file mode 100644 index f9e99e0474a41..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-05-21-46-45.bpo-18374.qgE0H3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances -which had a too large value in some situations. diff --git a/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rs= t b/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst deleted file mode 100644 index 6584d3ebe1ed8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-07-21-09-08.bpo-37520.Gg0KD6.rst +++ /dev/null @@ -1 +0,0 @@ -Correct behavior for zipfile.Path.parent when the path object identifies a s= ubdirectory. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-07-08-03-15-04.bpo-37502.qZGC4g.rs= t b/Misc/NEWS.d/next/Library/2019-07-08-03-15-04.bpo-37502.qZGC4g.rst deleted file mode 100644 index 4eb6d0974bde1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-08-03-15-04.bpo-37502.qZGC4g.rst +++ /dev/null @@ -1 +0,0 @@ -pickle.loads() no longer raises TypeError when the buffers argument is set t= o None diff --git a/Misc/NEWS.d/next/Library/2019-07-09-05-44-39.bpo-36993.4javqu.rs= t b/Misc/NEWS.d/next/Library/2019-07-09-05-44-39.bpo-36993.4javqu.rst deleted file mode 100644 index 009e07b92d22d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-09-05-44-39.bpo-36993.4javqu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve error reporting for corrupt zip files with bad zip64 extra data. Pat= ch -by Daniel Hillier. diff --git a/Misc/NEWS.d/next/Library/2019-07-09-11-20-21.bpo-37482.auzvev.rs= t b/Misc/NEWS.d/next/Library/2019-07-09-11-20-21.bpo-37482.auzvev.rst deleted file mode 100644 index e09ff63eedc43..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-09-11-20-21.bpo-37482.auzvev.rst +++ /dev/null @@ -1 +0,0 @@ -Fix serialization of display name in originator or destination address field= s with both encoded words and special chars. diff --git a/Misc/NEWS.d/next/Library/2019-07-09-19-38-26.bpo-37531.GX7s8S.rs= t b/Misc/NEWS.d/next/Library/2019-07-09-19-38-26.bpo-37531.GX7s8S.rst deleted file mode 100644 index aaf1052bd3c1b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-09-19-38-26.bpo-37531.GX7s8S.rst +++ /dev/null @@ -1,2 +0,0 @@ -"python3 -m test -jN --timeout=3DTIMEOUT" now kills a worker process if it r= uns -longer than *TIMEOUT* seconds. diff --git a/Misc/NEWS.d/next/Library/2019-07-10-23-07-11.bpo-21478.cCw9rF.rs= t b/Misc/NEWS.d/next/Library/2019-07-10-23-07-11.bpo-21478.cCw9rF.rst deleted file mode 100644 index 0ac9b8eadcab8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-10-23-07-11.bpo-21478.cCw9rF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Record calls to parent when autospecced object is attached to a mock using -:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-07-13-10-59-43.bpo-37579.B1Tq9i.rs= t b/Misc/NEWS.d/next/Library/2019-07-13-10-59-43.bpo-37579.B1Tq9i.rst deleted file mode 100644 index ad52cf2a06cca..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-13-10-59-43.bpo-37579.B1Tq9i.rst +++ /dev/null @@ -1,4 +0,0 @@ -Return :exc:`NotImplemented` in Python implementation of ``__eq__`` for -:class:`~datetime.timedelta` and :class:`~datetime.time` when the other -object being compared is not of the same type to match C implementation. -Patch by Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-07-13-13-40-12.bpo-18378.NHcojp.rs= t b/Misc/NEWS.d/next/Library/2019-07-13-13-40-12.bpo-18378.NHcojp.rst deleted file mode 100644 index 6dda8abf15d54..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-13-13-40-12.bpo-18378.NHcojp.rst +++ /dev/null @@ -1 +0,0 @@ -Recognize "UTF-8" as a valid value for LC_CTYPE in locale._parse_localename. diff --git a/Misc/NEWS.d/next/Library/2019-07-13-16-02-48.bpo-37587.fd-1aF.rs= t b/Misc/NEWS.d/next/Library/2019-07-13-16-02-48.bpo-37587.fd-1aF.rst deleted file mode 100644 index 80a89feab0ce8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-13-16-02-48.bpo-37587.fd-1aF.rst +++ /dev/null @@ -1 +0,0 @@ -Make json.loads faster for long strings. (Patch by Marco Paolini) diff --git a/Misc/NEWS.d/next/Library/2019-07-17-06-54-43.bpo-37491.op0aMs.rs= t b/Misc/NEWS.d/next/Library/2019-07-17-06-54-43.bpo-37491.op0aMs.rst deleted file mode 100644 index af4287ba478be..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-17-06-54-43.bpo-37491.op0aMs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``IndexError`` when parsing email headers with unexpectedly ending -bare-quoted string value. Patch by Abhilash Raj. diff --git a/Misc/NEWS.d/next/Library/2019-07-17-11-10-08.bpo-34443.OFnGqz.rs= t b/Misc/NEWS.d/next/Library/2019-07-17-11-10-08.bpo-34443.OFnGqz.rst deleted file mode 100644 index 8987a792b59c4..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-17-11-10-08.bpo-34443.OFnGqz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Exceptions from :mod:`enum` now use the ``__qualname`` of the enum class in -the exception message instead of the ``__name__``. diff --git a/Misc/NEWS.d/next/Library/2019-07-19-01-46-56.bpo-16970.GEASf5.rs= t b/Misc/NEWS.d/next/Library/2019-07-19-01-46-56.bpo-16970.GEASf5.rst deleted file mode 100644 index 7285b8176032f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-19-01-46-56.bpo-16970.GEASf5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adding a value error when an invalid value in passed to nargs -Patch by Robert Leenders diff --git a/Misc/NEWS.d/next/Library/2019-07-19-16-06-48.bpo-29446.iXGuoi.rs= t b/Misc/NEWS.d/next/Library/2019-07-19-16-06-48.bpo-29446.iXGuoi.rst deleted file mode 100644 index 9afda7efe4510..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-19-16-06-48.bpo-29446.iXGuoi.rst +++ /dev/null @@ -1 +0,0 @@ -Make `from tkinter import *` import only the expected objects. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-07-19-20-13-48.bpo-37555.S5am28.rs= t b/Misc/NEWS.d/next/Library/2019-07-19-20-13-48.bpo-37555.S5am28.rst deleted file mode 100644 index 16d1d62d30960..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-19-20-13-48.bpo-37555.S5am28.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix `NonCallableMock._call_matcher` returning tuple instead of `_Call` object -when `self._spec_signature` exists. Patch by Elizabeth Uselton \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-07-19-22-44-41.bpo-36324.1VjywS.rs= t b/Misc/NEWS.d/next/Library/2019-07-19-22-44-41.bpo-36324.1VjywS.rst deleted file mode 100644 index 2e41211c685e3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-19-22-44-41.bpo-36324.1VjywS.rst +++ /dev/null @@ -1 +0,0 @@ -Make internal attributes for statistics.NormalDist() private. diff --git a/Misc/NEWS.d/next/Library/2019-07-20-01-17-43.bpo-36161.Fzf-f9.rs= t b/Misc/NEWS.d/next/Library/2019-07-20-01-17-43.bpo-36161.Fzf-f9.rst deleted file mode 100644 index b31496c701744..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-20-01-17-43.bpo-36161.Fzf-f9.rst +++ /dev/null @@ -1 +0,0 @@ -In :mod:`posix`, use ``ttyname_r`` instead of ``ttyname`` for thread safety. diff --git a/Misc/NEWS.d/next/Library/2019-07-21-20-59-31.bpo-37642.L61Bvy.rs= t b/Misc/NEWS.d/next/Library/2019-07-21-20-59-31.bpo-37642.L61Bvy.rst deleted file mode 100644 index 09ff257597e86..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-21-20-59-31.bpo-37642.L61Bvy.rst +++ /dev/null @@ -1,3 +0,0 @@ -Allowed the pure Python implementation of :class:`datetime.timezone` to repr= esent -sub-minute offsets close to minimum and maximum boundaries, specifically in = the -ranges (23:59, 24:00) and (-23:59, 24:00). Patch by Ngalim Siregar diff --git a/Misc/NEWS.d/next/Library/2019-07-24-14-38-53.bpo-37663.h4-9-1.rs= t b/Misc/NEWS.d/next/Library/2019-07-24-14-38-53.bpo-37663.h4-9-1.rst deleted file mode 100644 index 1f9f9d9e44a79..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-24-14-38-53.bpo-37663.h4-9-1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Bring consistency to venv shell activation scripts by always using -__VENV_PROMPT__. diff --git a/Misc/NEWS.d/next/Library/2019-07-24-18-27-44.bpo-37664.o-GYZC.rs= t b/Misc/NEWS.d/next/Library/2019-07-24-18-27-44.bpo-37664.o-GYZC.rst deleted file mode 100644 index f12590540eb76..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-24-18-27-44.bpo-37664.o-GYZC.rst +++ /dev/null @@ -1 +0,0 @@ -Update wheels bundled with ensurepip (pip 19.2.3 and setuptools 41.2.0) diff --git a/Misc/NEWS.d/next/Library/2019-07-25-10-28-40.bpo-37354.RT3_3H.rs= t b/Misc/NEWS.d/next/Library/2019-07-25-10-28-40.bpo-37354.RT3_3H.rst deleted file mode 100644 index a314bcc9bf90f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-25-10-28-40.bpo-37354.RT3_3H.rst +++ /dev/null @@ -1 +0,0 @@ -Make Activate.ps1 Powershell script static to allow for signing it. diff --git a/Misc/NEWS.d/next/Library/2019-07-26-00-12-29.bpo-37685.TqckMZ.rs= t b/Misc/NEWS.d/next/Library/2019-07-26-00-12-29.bpo-37685.TqckMZ.rst deleted file mode 100644 index d1179a620c171..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-26-00-12-29.bpo-37685.TqckMZ.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fixed ``__eq__``, ``__lt__`` etc implementations in some classes. They now -return :data:`NotImplemented` for unsupported type of the other operand. -This allows the other operand to play role (for example the equality -comparison with :data:`~unittest.mock.ANY` will return ``True``). diff --git a/Misc/NEWS.d/next/Library/2019-07-26-22-30-01.bpo-37691.1Li3rx.rs= t b/Misc/NEWS.d/next/Library/2019-07-26-22-30-01.bpo-37691.1Li3rx.rst deleted file mode 100644 index 048478c008e80..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-26-22-30-01.bpo-37691.1Li3rx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Let math.dist() accept coordinates as sequences (or iterables) rather than -just tuples. diff --git a/Misc/NEWS.d/next/Library/2019-07-27-10-14-45.bpo-29553.TVeIDe.rs= t b/Misc/NEWS.d/next/Library/2019-07-27-10-14-45.bpo-29553.TVeIDe.rst deleted file mode 100644 index 3472db7bf2099..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-27-10-14-45.bpo-29553.TVeIDe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :meth:`argparse.ArgumentParser.format_usage` for mutually exclusive gr= oups. -Patch by Andrew Nester. diff --git a/Misc/NEWS.d/next/Library/2019-07-27-18-00-43.bpo-37689.glEmZi.rs= t b/Misc/NEWS.d/next/Library/2019-07-27-18-00-43.bpo-37689.glEmZi.rst deleted file mode 100644 index 2787f9e849c20..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-27-18-00-43.bpo-37689.glEmZi.rst +++ /dev/null @@ -1 +0,0 @@ -Add :meth:`is_relative_to` in :class:`PurePath` to determine whether or not = one path is relative to another. diff --git a/Misc/NEWS.d/next/Library/2019-07-27-20-21-03.bpo-37695.QANdvg.rs= t b/Misc/NEWS.d/next/Library/2019-07-27-20-21-03.bpo-37695.QANdvg.rst deleted file mode 100644 index ca6c11641ed6a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-27-20-21-03.bpo-37695.QANdvg.rst +++ /dev/null @@ -1 +0,0 @@ -Correct :func:`curses.unget_wch` error message. Patch by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-07-28-17-44-21.bpo-37697.7UV5d0.rs= t b/Misc/NEWS.d/next/Library/2019-07-28-17-44-21.bpo-37697.7UV5d0.rst deleted file mode 100644 index 6c78d7cd17c42..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-28-17-44-21.bpo-37697.7UV5d0.rst +++ /dev/null @@ -1 +0,0 @@ -Syncronize ``importlib.metadata`` with `importlib_metadata 0.19 `_, improving handling= of EGG-INFO files and fixing a crash when entry point names contained colons. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-07-28-22-25-25.bpo-37685._3bN9f.rs= t b/Misc/NEWS.d/next/Library/2019-07-28-22-25-25.bpo-37685._3bN9f.rst deleted file mode 100644 index ba60057e6fb66..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-28-22-25-25.bpo-37685._3bN9f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed comparisons of :class:`datetime.timedelta` and -:class:`datetime.timezone`. diff --git a/Misc/NEWS.d/next/Library/2019-07-29-21-39-45.bpo-11953.4Hpwf9.rs= t b/Misc/NEWS.d/next/Library/2019-07-29-21-39-45.bpo-11953.4Hpwf9.rst deleted file mode 100644 index 62f3c44c284ea..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-29-21-39-45.bpo-11953.4Hpwf9.rst +++ /dev/null @@ -1 +0,0 @@ -Completing WSA* error codes in :mod:`socket`. diff --git a/Misc/NEWS.d/next/Library/2019-07-30-01-27-29.bpo-37268.QDmA44.rs= t b/Misc/NEWS.d/next/Library/2019-07-30-01-27-29.bpo-37268.QDmA44.rst deleted file mode 100644 index d5c7b1d2fc668..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-30-01-27-29.bpo-37268.QDmA44.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`parser` module is deprecated and will be removed in future -versions of Python. diff --git a/Misc/NEWS.d/next/Library/2019-07-30-22-41-05.bpo-32178.X-IFLe.rs= t b/Misc/NEWS.d/next/Library/2019-07-30-22-41-05.bpo-32178.X-IFLe.rst deleted file mode 100644 index 5e7a2e964d93d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-30-22-41-05.bpo-32178.X-IFLe.rst +++ /dev/null @@ -1 +0,0 @@ -Fix IndexError in :mod:`email` package when trying to parse invalid address = fields starting with ``:``. diff --git a/Misc/NEWS.d/next/Library/2019-07-31-15-52-51.bpo-35943.-KswoB.rs= t b/Misc/NEWS.d/next/Library/2019-07-31-15-52-51.bpo-35943.-KswoB.rst deleted file mode 100644 index b1c55608f598f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-31-15-52-51.bpo-35943.-KswoB.rst +++ /dev/null @@ -1,2 +0,0 @@ -The function :c:func:`PyImport_GetModule` now ensures any module it returns = is fully initialized. -Patch by Joannah Nanjekye. diff --git a/Misc/NEWS.d/next/Library/2019-07-31-16-49-01.bpo-37723.zq6tw8.rs= t b/Misc/NEWS.d/next/Library/2019-07-31-16-49-01.bpo-37723.zq6tw8.rst deleted file mode 100644 index 65507bd0dc91a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-07-31-16-49-01.bpo-37723.zq6tw8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix performance regression on regular expression parsing with huge -character sets. Patch by Yann Vaginay. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-08-01-17-11-16.bpo-37738.A3WWcT.rs= t b/Misc/NEWS.d/next/Library/2019-08-01-17-11-16.bpo-37738.A3WWcT.rst deleted file mode 100644 index 7e70a9c2231af..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-01-17-11-16.bpo-37738.A3WWcT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the implementation of curses ``addch(str, color_pair)``: pass the color -pair to ``setcchar()``, instead of always passing 0 as the color pair. diff --git a/Misc/NEWS.d/next/Library/2019-08-02-14-01-25.bpo-37742.f4Xn9S.rs= t b/Misc/NEWS.d/next/Library/2019-08-02-14-01-25.bpo-37742.f4Xn9S.rst deleted file mode 100644 index 300ced3fec6b0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-02-14-01-25.bpo-37742.f4Xn9S.rst +++ /dev/null @@ -1,5 +0,0 @@ -The logging.getLogger() API now returns the root logger when passed the name -'root', whereas previously it returned a non-root logger named 'root'. This -could affect cases where user code explicitly wants a non-root logger named -'root', or instantiates a logger using logging.getLogger(__name__) in some -top-level module called 'root.py'. diff --git a/Misc/NEWS.d/next/Library/2019-08-02-16-44-42.bpo-18049.OA4qBL.rs= t b/Misc/NEWS.d/next/Library/2019-08-02-16-44-42.bpo-18049.OA4qBL.rst deleted file mode 100644 index 36a4de384cc08..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-02-16-44-42.bpo-18049.OA4qBL.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add definition of THREAD_STACK_SIZE for AIX in Python/thread_pthread.h -The default thread stacksize caused crashes with the default recursion limit -Patch by M Felt diff --git a/Misc/NEWS.d/next/Library/2019-08-04-11-47-58.bpo-28292.vkihH5.rs= t b/Misc/NEWS.d/next/Library/2019-08-04-11-47-58.bpo-28292.vkihH5.rst deleted file mode 100644 index 478a1b03c195e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-04-11-47-58.bpo-28292.vkihH5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Mark calendar.py helper functions as being private. The follows PEP 8 -guidance to maintain the style conventions in the module and it addresses a -known case of user confusion. diff --git a/Misc/NEWS.d/next/Library/2019-08-04-17-22-33.bpo-37449.ycbL2z.rs= t b/Misc/NEWS.d/next/Library/2019-08-04-17-22-33.bpo-37449.ycbL2z.rst deleted file mode 100644 index b34bfea9816f1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-04-17-22-33.bpo-37449.ycbL2z.rst +++ /dev/null @@ -1,2 +0,0 @@ -`ensurepip` now uses `importlib.resources.read_binary()` to read data instea= d of `pkgutil.get_data()`. -Patch by Joannah Nanjekye. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-08-06-21-30-58.bpo-34488.OqxVo8.rs= t b/Misc/NEWS.d/next/Library/2019-08-06-21-30-58.bpo-34488.OqxVo8.rst deleted file mode 100644 index 1e7e5a6ba0bc3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-06-21-30-58.bpo-34488.OqxVo8.rst +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`writelines` method of :class:`io.BytesIO` is now slightly faster -when many small lines are passed. Patch by Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Library/2019-08-07-14-49-22.bpo-37785.y7OlT8.rs= t b/Misc/NEWS.d/next/Library/2019-08-07-14-49-22.bpo-37785.y7OlT8.rst deleted file mode 100644 index 2d3aa4f9a75a0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-07-14-49-22.bpo-37785.y7OlT8.rst +++ /dev/null @@ -1 +0,0 @@ -Fix xgettext warnings in :mod:`argparse`. diff --git a/Misc/NEWS.d/next/Library/2019-08-07-19-34-07.bpo-18578.xfvdb_.rs= t b/Misc/NEWS.d/next/Library/2019-08-07-19-34-07.bpo-18578.xfvdb_.rst deleted file mode 100644 index cc0e02fdb3940..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-07-19-34-07.bpo-18578.xfvdb_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Renamed and documented `test.bytecode_helper` as `test.support.bytecode_help= er`. -Patch by Joannah Nanjekye. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-08-07-23-48-09.bpo-37772.hLCvdn.rs= t b/Misc/NEWS.d/next/Library/2019-08-07-23-48-09.bpo-37772.hLCvdn.rst deleted file mode 100644 index f9ec6a33b07ba..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-07-23-48-09.bpo-37772.hLCvdn.rst +++ /dev/null @@ -1 +0,0 @@ -In ``zipfile.Path``, when adding implicit dirs, ensure that ancestral direct= ories are added and that duplicates are excluded. diff --git a/Misc/NEWS.d/next/Library/2019-08-10-12-33-27.bpo-37810.d4zbvB.rs= t b/Misc/NEWS.d/next/Library/2019-08-10-12-33-27.bpo-37810.d4zbvB.rst deleted file mode 100644 index 3e0b31775d07f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-10-12-33-27.bpo-37810.d4zbvB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :mod:`difflib` ``?`` hint in diff output when dealing with tabs. Patch -by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-08-10-18-50-04.bpo-14465.qZGC4g.rs= t b/Misc/NEWS.d/next/Library/2019-08-10-18-50-04.bpo-14465.qZGC4g.rst deleted file mode 100644 index 5f8b7a0934d35..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-10-18-50-04.bpo-14465.qZGC4g.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add an xml.etree.ElementTree.indent() function for pretty-printing XML trees. -Contributed by Stefan Behnel. diff --git a/Misc/NEWS.d/next/Library/2019-08-11-10-34-19.bpo-37819.LVJls-.rs= t b/Misc/NEWS.d/next/Library/2019-08-11-10-34-19.bpo-37819.LVJls-.rst deleted file mode 100644 index cfc1f1afb4f76..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-11-10-34-19.bpo-37819.LVJls-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add Fraction.as_integer_ratio() to match the corresponding methods in bool, -int, float, and decimal. diff --git a/Misc/NEWS.d/next/Library/2019-08-12-23-07-47.bpo-37804.Ene6L-.rs= t b/Misc/NEWS.d/next/Library/2019-08-12-23-07-47.bpo-37804.Ene6L-.rst deleted file mode 100644 index ebbcb5aa7788f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-12-23-07-47.bpo-37804.Ene6L-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the deprecated method `threading.Thread.isAlive()`. Patch by Dong-hee -Na. diff --git a/Misc/NEWS.d/next/Library/2019-08-14-13-51-24.bpo-37798.AmXrik.rs= t b/Misc/NEWS.d/next/Library/2019-08-14-13-51-24.bpo-37798.AmXrik.rst deleted file mode 100644 index 620f0ecdf41a6..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-14-13-51-24.bpo-37798.AmXrik.rst +++ /dev/null @@ -1 +0,0 @@ -Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Dong-hee Na diff --git a/Misc/NEWS.d/next/Library/2019-08-14-15-34-23.bpo-21131.0MMQRi.rs= t b/Misc/NEWS.d/next/Library/2019-08-14-15-34-23.bpo-21131.0MMQRi.rst deleted file mode 100644 index d330aca1c17d2..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-14-15-34-23.bpo-21131.0MMQRi.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix ``faulthandler.register(chain=3DTrue)`` stack. faulthandler now allocate= s a -dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just ``SIGSTKSZ`` bytes. -Calling the previous signal handler in faulthandler signal handler uses more -than ``SIGSTKSZ`` bytes of stack memory on some platforms. diff --git a/Misc/NEWS.d/next/Library/2019-08-14-20-46-39.bpo-37863.CkXqgX.rs= t b/Misc/NEWS.d/next/Library/2019-08-14-20-46-39.bpo-37863.CkXqgX.rst deleted file mode 100644 index 90df6e9cb6526..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-14-20-46-39.bpo-37863.CkXqgX.rst +++ /dev/null @@ -1 +0,0 @@ -Optimizations for Fraction.__hash__ suggested by Tim Peters. diff --git a/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rs= t b/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst deleted file mode 100644 index 662e7dc410050..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-14-21-41-07.bpo-37811.d1xYj7.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix ``socket`` module's ``socket.connect(address)`` function being unable to -establish connection in case of interrupted system call. The problem was -observed on all OSes which ``poll(2)`` system call can take only -non-negative integers and -1 as a timeout value. diff --git a/Misc/NEWS.d/next/Library/2019-08-17-22-33-54.bpo-37868.hp64fi.rs= t b/Misc/NEWS.d/next/Library/2019-08-17-22-33-54.bpo-37868.hp64fi.rst deleted file mode 100644 index 7f342e1ee354c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-17-22-33-54.bpo-37868.hp64fi.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix dataclasses.is_dataclass when given an instance that never raises -AttributeError in __getattr__. That is, an object that returns something -for __dataclass_fields__ even if it's not a dataclass. diff --git a/Misc/NEWS.d/next/Library/2019-08-19-10-31-41.bpo-37885.4Nc9sp.rs= t b/Misc/NEWS.d/next/Library/2019-08-19-10-31-41.bpo-37885.4Nc9sp.rst deleted file mode 100644 index 055d02970146e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-19-10-31-41.bpo-37885.4Nc9sp.rst +++ /dev/null @@ -1 +0,0 @@ -venv: Don't generate unset variable warning on deactivate. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-08-20-05-17-32.bpo-32793.cgpXl6.rs= t b/Misc/NEWS.d/next/Library/2019-08-20-05-17-32.bpo-32793.cgpXl6.rst deleted file mode 100644 index f715a816efda9..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-20-05-17-32.bpo-32793.cgpXl6.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a duplicated debug message when :meth:`smtplib.SMTP.connect` is called. diff --git a/Misc/NEWS.d/next/Library/2019-08-21-13-43-04.bpo-37851.mIIfD_.rs= t b/Misc/NEWS.d/next/Library/2019-08-21-13-43-04.bpo-37851.mIIfD_.rst deleted file mode 100644 index 997011f023f27..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-21-13-43-04.bpo-37851.mIIfD_.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :mod:`faulthandler` module no longer allocates its alternative stack at -Python startup. Now the stack is only allocated at the first faulthandler -usage. diff --git a/Misc/NEWS.d/next/Library/2019-08-21-16-38-56.bpo-9938.t3G7N9.rst= b/Misc/NEWS.d/next/Library/2019-08-21-16-38-56.bpo-9938.t3G7N9.rst deleted file mode 100644 index 4cb89893159e5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-21-16-38-56.bpo-9938.t3G7N9.rst +++ /dev/null @@ -1 +0,0 @@ -Add optional keyword argument ``exit_on_error`` for :class:`ArgumentParser`. diff --git a/Misc/NEWS.d/next/Library/2019-08-22-01-49-05.bpo-32554.4xiXyM.rs= t b/Misc/NEWS.d/next/Library/2019-08-22-01-49-05.bpo-32554.4xiXyM.rst deleted file mode 100644 index 752cf48a4543a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-22-01-49-05.bpo-32554.4xiXyM.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate having random.seed() call hash on arbitrary types. diff --git a/Misc/NEWS.d/next/Library/2019-08-22-16-13-27.bpo-37915.xyoZI5.rs= t b/Misc/NEWS.d/next/Library/2019-08-22-16-13-27.bpo-37915.xyoZI5.rst deleted file mode 100644 index 1dc9ea4b8cf8c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-22-16-13-27.bpo-37915.xyoZI5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a segmentation fault that appeared when comparing instances of -``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo -Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-08-23-00-55-19.bpo-26589.M1xyxG.rs= t b/Misc/NEWS.d/next/Library/2019-08-23-00-55-19.bpo-26589.M1xyxG.rst deleted file mode 100644 index ef132dcceb2c8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-23-00-55-19.bpo-26589.M1xyxG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added a new status code to the http module: 451 -UNAVAILABLE_FOR_LEGAL_REASONS diff --git a/Misc/NEWS.d/next/Library/2019-08-24-16-54-49.bpo-37798.7mRQCk.rs= t b/Misc/NEWS.d/next/Library/2019-08-24-16-54-49.bpo-37798.7mRQCk.rst deleted file mode 100644 index 25cfa00478863..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-24-16-54-49.bpo-37798.7mRQCk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update test_statistics.py to verify that the statistics module works well -for both C and Python implementations. Patch by Dong-hee Na diff --git a/Misc/NEWS.d/next/Library/2019-08-25-14-56-42.bpo-36917.GBxdw2.rs= t b/Misc/NEWS.d/next/Library/2019-08-25-14-56-42.bpo-36917.GBxdw2.rst deleted file mode 100644 index 3509a7530b891..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-25-14-56-42.bpo-36917.GBxdw2.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add default implementation of the :meth:`ast.NodeVisitor.visit_Constant` -method which emits a deprecation warning and calls corresponding methody -``visit_Num()``, ``visit_Str()``, etc. diff --git a/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rs= t b/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst deleted file mode 100644 index 785b06b6482c3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst +++ /dev/null @@ -1 +0,0 @@ -Restores instantiation of Windows IOCP event loops from the non-main thread. diff --git a/Misc/NEWS.d/next/Library/2019-08-26-10-45-51.bpo-37950.-K1IKT.rs= t b/Misc/NEWS.d/next/Library/2019-08-26-10-45-51.bpo-37950.-K1IKT.rst deleted file mode 100644 index ded80d3b00ef0..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-26-10-45-51.bpo-37950.-K1IKT.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :func:`ast.dump` when call with incompletely initialized node. diff --git a/Misc/NEWS.d/next/Library/2019-08-27-03-53-26.bpo-36205.AfkGRl.rs= t b/Misc/NEWS.d/next/Library/2019-08-27-03-53-26.bpo-36205.AfkGRl.rst deleted file mode 100644 index 50cda34fbbd38..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-03-53-26.bpo-36205.AfkGRl.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the rusage implementation of time.process_time() to correctly report the= sum of the system and user CPU time. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-08-27-10-03-48.bpo-37951.MfRQgL.rs= t b/Misc/NEWS.d/next/Library/2019-08-27-10-03-48.bpo-37951.MfRQgL.rst deleted file mode 100644 index 18e4c620bdea5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-10-03-48.bpo-37951.MfRQgL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Most features of the subprocess module now work again in subinterpreters. -Only *preexec_fn* is restricted in subinterpreters. diff --git a/Misc/NEWS.d/next/Library/2019-08-27-10-30-44.bpo-37961.4nm0zZ.rs= t b/Misc/NEWS.d/next/Library/2019-08-27-10-30-44.bpo-37961.4nm0zZ.rst deleted file mode 100644 index ebfff77decff3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-10-30-44.bpo-37961.4nm0zZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a ``total_nframe`` field to the traces collected by the tracemalloc modu= le. -This field indicates the original number of frames before it was truncated. diff --git a/Misc/NEWS.d/next/Library/2019-08-27-10-52-13.bpo-37960.CTY7Lw.rs= t b/Misc/NEWS.d/next/Library/2019-08-27-10-52-13.bpo-37960.CTY7Lw.rst deleted file mode 100644 index 421cfb9c38e1d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-10-52-13.bpo-37960.CTY7Lw.rst +++ /dev/null @@ -1,2 +0,0 @@ -``repr()`` of buffered and text streams now silences only expected -exceptions when get the value of "name" and "mode" attributes. diff --git a/Misc/NEWS.d/next/Library/2019-08-27-21-19-28.bpo-37964.SxdnsF.rs= t b/Misc/NEWS.d/next/Library/2019-08-27-21-19-28.bpo-37964.SxdnsF.rst deleted file mode 100644 index c25e64329c4c8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-27-21-19-28.bpo-37964.SxdnsF.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``F_GETPATH`` command to :mod:`fcntl`. diff --git a/Misc/NEWS.d/next/Library/2019-08-28-14-04-18.bpo-37965.7xGE-C.rs= t b/Misc/NEWS.d/next/Library/2019-08-28-14-04-18.bpo-37965.7xGE-C.rst deleted file mode 100644 index 116a9e49dccc1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-28-14-04-18.bpo-37965.7xGE-C.rst +++ /dev/null @@ -1 +0,0 @@ -Fix C compiler warning caused by distutils.ccompiler.CCompiler.has_function. diff --git a/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rs= t b/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst deleted file mode 100644 index 73d9ef77762b7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst +++ /dev/null @@ -1,5 +0,0 @@ -Subscripts to the `unittest.mock.call` objects now receive the same chaining= mechanism as any other custom attributes, so that the following usage no lon= ger raises a `TypeError`: - - call().foo().__getitem__('bar') - -Patch by blhsing diff --git a/Misc/NEWS.d/next/Library/2019-08-29-01-19-13.bpo-10978.J6FQYY.rs= t b/Misc/NEWS.d/next/Library/2019-08-29-01-19-13.bpo-10978.J6FQYY.rst deleted file mode 100644 index 2b8f300fc2804..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-29-01-19-13.bpo-10978.J6FQYY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Semaphores and BoundedSemaphores can now release more than one waiting -thread at a time. diff --git a/Misc/NEWS.d/next/Library/2019-08-29-16-41-36.bpo-37834.FThnsh.rs= t b/Misc/NEWS.d/next/Library/2019-08-29-16-41-36.bpo-37834.FThnsh.rst deleted file mode 100644 index afbbb3313a5b2..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-29-16-41-36.bpo-37834.FThnsh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent shutil.rmtree exception when built on non-Windows system without fd -system call support, like older versions of macOS. diff --git a/Misc/NEWS.d/next/Library/2019-08-29-18-48-48.bpo-37587.N7TGTC.rs= t b/Misc/NEWS.d/next/Library/2019-08-29-18-48-48.bpo-37587.N7TGTC.rst deleted file mode 100644 index 92bebeea30215..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-29-18-48-48.bpo-37587.N7TGTC.rst +++ /dev/null @@ -1,2 +0,0 @@ -``_json.scanstring`` is now up to 3x faster when there are many backslash -escaped characters in the JSON string. diff --git a/Misc/NEWS.d/next/Library/2019-08-30-11-21-10.bpo-37140.cFAX-a.rs= t b/Misc/NEWS.d/next/Library/2019-08-30-11-21-10.bpo-37140.cFAX-a.rst deleted file mode 100644 index 4eaa226147f9e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-30-11-21-10.bpo-37140.cFAX-a.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a ctypes regression of Python 3.8. When a ctypes.Structure is passed by -copy to a function, ctypes internals created a temporary object which had -the side effect of calling the structure finalizer (__del__) twice. The -Python semantics requires a finalizer to be called exactly once. Fix ctypes -internals to no longer call the finalizer twice. diff --git a/Misc/NEWS.d/next/Library/2019-08-31-01-52-59.bpo-34410.7KbWZQ.rs= t b/Misc/NEWS.d/next/Library/2019-08-31-01-52-59.bpo-34410.7KbWZQ.rst deleted file mode 100644 index 64e778ee0913c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-31-01-52-59.bpo-34410.7KbWZQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a crash in the :func:`tee` iterator when re-enter it. RuntimeError is -now raised in this case. diff --git a/Misc/NEWS.d/next/Library/2019-08-31-13-36-09.bpo-37995.rS8HzT.rs= t b/Misc/NEWS.d/next/Library/2019-08-31-13-36-09.bpo-37995.rS8HzT.rst deleted file mode 100644 index 19482b644e14d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-08-31-13-36-09.bpo-37995.rS8HzT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added the *indent* option to :func:`ast.dump` which allows it to produce a -multiline indented output. diff --git a/Misc/NEWS.d/next/Library/2019-09-02-13-37-27.bpo-38006.Y7vA0Q.rs= t b/Misc/NEWS.d/next/Library/2019-09-02-13-37-27.bpo-38006.Y7vA0Q.rst deleted file mode 100644 index ff064ad3f1a49..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-02-13-37-27.bpo-38006.Y7vA0Q.rst +++ /dev/null @@ -1,3 +0,0 @@ -weakref.WeakValueDictionary defines a local remove() function used as -callback for weak references. This function was created with a closure. -Modify the implementation to avoid the closure. diff --git a/Misc/NEWS.d/next/Library/2019-09-02-14-30-39.bpo-38010.JOnz9Z.rs= t b/Misc/NEWS.d/next/Library/2019-09-02-14-30-39.bpo-38010.JOnz9Z.rst deleted file mode 100644 index a97f9b7d9a401..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-02-14-30-39.bpo-38010.JOnz9Z.rst +++ /dev/null @@ -1 +0,0 @@ -In ``importlib.metadata`` sync with ``importlib_metadata`` 0.20, clarifying = behavior of ``files()`` and fixing issue where only one requirement was retur= ned for ``requires()`` on ``dist-info`` packages. diff --git a/Misc/NEWS.d/next/Library/2019-09-03-01-41-35.bpo-35923.lYpKbY.rs= t b/Misc/NEWS.d/next/Library/2019-09-03-01-41-35.bpo-35923.lYpKbY.rst deleted file mode 100644 index bd2bba75675b7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-03-01-41-35.bpo-35923.lYpKbY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update :class:`importlib.machinery.BuiltinImporter` to use ``loader._ORIGIN`` -instead of a hardcoded value. Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2019-09-04-20-34-14.bpo-38026.0LLRX-.rs= t b/Misc/NEWS.d/next/Library/2019-09-04-20-34-14.bpo-38026.0LLRX-.rst deleted file mode 100644 index 166cd867514ca..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-04-20-34-14.bpo-38026.0LLRX-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed :func:`inspect.getattr_static` used ``isinstance`` while it should -avoid dynamic lookup. diff --git a/Misc/NEWS.d/next/Library/2019-09-06-17-40-34.bpo-37953.db5FQq.rs= t b/Misc/NEWS.d/next/Library/2019-09-06-17-40-34.bpo-37953.db5FQq.rst deleted file mode 100644 index 4eff4f7479aad..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-06-17-40-34.bpo-37953.db5FQq.rst +++ /dev/null @@ -1,2 +0,0 @@ -In :mod:`typing`, improved the ``__hash__`` and ``__eq__`` methods for -:class:`ForwardReferences`. diff --git a/Misc/NEWS.d/next/Library/2019-09-07-12-32-50.bpo-38049.xKP4tf.rs= t b/Misc/NEWS.d/next/Library/2019-09-07-12-32-50.bpo-38049.xKP4tf.rst deleted file mode 100644 index 9f17683032f14..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-07-12-32-50.bpo-38049.xKP4tf.rst +++ /dev/null @@ -1 +0,0 @@ -Added command-line interface for the :mod:`ast` module. diff --git a/Misc/NEWS.d/next/Library/2019-09-08-11-36-50.bpo-38059.8SA6co.rs= t b/Misc/NEWS.d/next/Library/2019-09-08-11-36-50.bpo-38059.8SA6co.rst deleted file mode 100644 index 001952ae12613..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-08-11-36-50.bpo-38059.8SA6co.rst +++ /dev/null @@ -1 +0,0 @@ -inspect.py now uses sys.exit() instead of exit() diff --git a/Misc/NEWS.d/next/Library/2019-09-09-14-39-47.bpo-38066.l9mWv-.rs= t b/Misc/NEWS.d/next/Library/2019-09-09-14-39-47.bpo-38066.l9mWv-.rst deleted file mode 100644 index a69924fe2aa41..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-09-14-39-47.bpo-38066.l9mWv-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Hide internal asyncio.Stream methods: feed_eof(), feed_data(), -set_exception() and set_transport(). diff --git a/Misc/NEWS.d/next/Library/2019-09-09-18-39-23.bpo-38037.B0UgFU.rs= t b/Misc/NEWS.d/next/Library/2019-09-09-18-39-23.bpo-38037.B0UgFU.rst deleted file mode 100644 index 607673bd9994b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-09-18-39-23.bpo-38037.B0UgFU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix reference counters in the :mod:`signal` module. diff --git a/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rs= t b/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst deleted file mode 100644 index 27fd1e46963c7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-10-10-59-50.bpo-37251.8zn2o3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Remove `__code__` check in AsyncMock that incorrectly -evaluated function specs as async objects but failed to evaluate classes -with `__await__` but no `__code__` attribute defined as async objects. diff --git a/Misc/NEWS.d/next/Library/2019-09-10-11-42-59.bpo-38086.w5TlG-.rs= t b/Misc/NEWS.d/next/Library/2019-09-10-11-42-59.bpo-38086.w5TlG-.rst deleted file mode 100644 index 40db53c97da4d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-10-11-42-59.bpo-38086.w5TlG-.rst +++ /dev/null @@ -1 +0,0 @@ -Update importlib.metadata with changes from `importlib_metadata 0.21 `_. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rs= t b/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst deleted file mode 100644 index abdf87a623889..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-10-15-52-55.bpo-35640.X0lp5f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow passing a :term:`path-like object` as ``directory`` argument to the -:class:`http.server.SimpleHTTPRequestHandler` class. Patch by G=C3=A9ry Ogam. diff --git a/Misc/NEWS.d/next/Library/2019-09-11-11-44-16.bpo-37488.S8CJUL.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-11-44-16.bpo-37488.S8CJUL.rst deleted file mode 100644 index 4f9041502a914..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-11-44-16.bpo-37488.S8CJUL.rst +++ /dev/null @@ -1 +0,0 @@ -Add warning to :meth:`datetime.utctimetuple`, :meth:`datetime.utcnow` and := meth:`datetime.utcfromtimestamp` . \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-09-11-14-45-30.bpo-38093.yQ6k7y.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-14-45-30.bpo-38093.yQ6k7y.rst deleted file mode 100644 index 24a53013cec78..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-14-45-30.bpo-38093.yQ6k7y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes AsyncMock so it doesn't crash when used with AsyncContextManagers -or AsyncIterators. diff --git a/Misc/NEWS.d/next/Library/2019-09-11-14-49-20.bpo-38110.A19Y-q.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-14-49-20.bpo-38110.A19Y-q.rst deleted file mode 100644 index 7b94a2e90a503..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-14-49-20.bpo-38110.A19Y-q.rst +++ /dev/null @@ -1,2 +0,0 @@ -The os.closewalk() implementation now uses the libc fdwalk() API on -platforms where it is available. diff --git a/Misc/NEWS.d/next/Library/2019-09-11-16-54-57.bpo-38121.SrSDzB.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-16-54-57.bpo-38121.SrSDzB.rst deleted file mode 100644 index 93eabcfaab397..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-16-54-57.bpo-38121.SrSDzB.rst +++ /dev/null @@ -1 +0,0 @@ -Update parameter names on functions in importlib.metadata matching the chang= es in the 0.22 release of importlib_metadata. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-09-11-20-27-41.bpo-37405.MG5xiY.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-20-27-41.bpo-37405.MG5xiY.rst deleted file mode 100644 index 09e1097342210..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-20-27-41.bpo-37405.MG5xiY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed regression bug for socket.getsockname() for non-CAN_ISOTP AF_CAN -address family sockets by returning a 1-tuple instead of string. diff --git a/Misc/NEWS.d/next/Library/2019-09-11-21-38-41.bpo-34037.LIAS_3.rs= t b/Misc/NEWS.d/next/Library/2019-09-11-21-38-41.bpo-34037.LIAS_3.rst deleted file mode 100644 index 75345160a2fa3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-11-21-38-41.bpo-34037.LIAS_3.rst +++ /dev/null @@ -1,4 +0,0 @@ -For :mod:`asyncio`, add a new coroutine :meth:`loop.shutdown_default_executo= r`. -The new coroutine provides an API to schedule an executor shutdown that waits -on the threadpool to finish closing. Also, :func:`asyncio.run` has been upda= ted -to utilize the new coroutine. Patch by Kyle Stanley. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst deleted file mode 100644 index f696707eadf74..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix parent class check in protocols to correctly identify the module that -provides a builtin protocol, instead of assuming they all come from the -:mod:`collections.abc` module diff --git a/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst deleted file mode 100644 index c2e3b6290d9ef..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-12-47-35.bpo-38132.KSFx1F.rst +++ /dev/null @@ -1,3 +0,0 @@ -The OpenSSL hashlib wrapper uses a simpler implementation. Several Macros -and pointless caches are gone. The hash name now comes from OpenSSL's EVP. -The algorithm name stays the same, except it is now always lower case. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-13-18-55.bpo-38134.gXJTbP.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-13-18-55.bpo-38134.gXJTbP.rst deleted file mode 100644 index fc134c203fdd8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-13-18-55.bpo-38134.gXJTbP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove obsolete copy of PBKDF2_HMAC_fast. All supported OpenSSL versions -contain a fast implementation. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-14-52-38.bpo-36991.1OcSm8.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-14-52-38.bpo-36991.1OcSm8.rst deleted file mode 100644 index c6fa852e94ad9..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-14-52-38.bpo-36991.1OcSm8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes a potential incorrect AttributeError exception escaping -ZipFile.extract() in some unsupported input error situations. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-14-54-45.bpo-9216.W7QMpC.rst= b/Misc/NEWS.d/next/Library/2019-09-12-14-54-45.bpo-9216.W7QMpC.rst deleted file mode 100644 index a97ca4b8b4f27..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-14-54-45.bpo-9216.W7QMpC.rst +++ /dev/null @@ -1,2 +0,0 @@ -hashlib constructors now support usedforsecurity flag to signal that a -hashing algorithm is not used in a security context. diff --git a/Misc/NEWS.d/next/Library/2019-09-12-18-41-35.bpo-38142.1I0Ch0.rs= t b/Misc/NEWS.d/next/Library/2019-09-12-18-41-35.bpo-38142.1I0Ch0.rst deleted file mode 100644 index 740b6f1cf096d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-12-18-41-35.bpo-38142.1I0Ch0.rst +++ /dev/null @@ -1 +0,0 @@ -The _hashlib OpenSSL wrapper extension module is now PEP-384 compliant. diff --git a/Misc/NEWS.d/next/Library/2019-09-13-08-55-43.bpo-38148.Lnww6D.rs= t b/Misc/NEWS.d/next/Library/2019-09-13-08-55-43.bpo-38148.Lnww6D.rst deleted file mode 100644 index 88c0809b1c2a4..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-13-08-55-43.bpo-38148.Lnww6D.rst +++ /dev/null @@ -1 +0,0 @@ -Add slots to :mod:`asyncio` transport classes, which can reduce memory usage. diff --git a/Misc/NEWS.d/next/Library/2019-09-13-09-24-58.bpo-38115.BOO-Y1.rs= t b/Misc/NEWS.d/next/Library/2019-09-13-09-24-58.bpo-38115.BOO-Y1.rst deleted file mode 100644 index 5119c0546e369..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-13-09-24-58.bpo-38115.BOO-Y1.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug in dis.findlinestarts() where it would return invalid bytecode off= sets. Document that a code object's co_lnotab can contain invalid bytecode of= fsets. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-09-13-12-18-51.bpo-38153.nHAbuJ.rs= t b/Misc/NEWS.d/next/Library/2019-09-13-12-18-51.bpo-38153.nHAbuJ.rst deleted file mode 100644 index 8a483c760adc7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-13-12-18-51.bpo-38153.nHAbuJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Names of hashing algorithms frome OpenSSL are now normalized to follow -Python's naming conventions. For example OpenSSL uses sha3-512 instead of -sha3_512 or blake2b512 instead of blake2b.=20 diff --git a/Misc/NEWS.d/next/Library/2019-09-13-14-54-33.bpo-34706.HWVpOY.rs= t b/Misc/NEWS.d/next/Library/2019-09-13-14-54-33.bpo-34706.HWVpOY.rst deleted file mode 100644 index 1df3742abd272..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-13-14-54-33.bpo-34706.HWVpOY.rst +++ /dev/null @@ -1 +0,0 @@ -Preserve subclassing in inspect.Signature.from_callable. diff --git a/Misc/NEWS.d/next/Library/2019-09-14-10-34-00.bpo-33936.8wCI_n.rs= t b/Misc/NEWS.d/next/Library/2019-09-14-10-34-00.bpo-33936.8wCI_n.rst deleted file mode 100644 index 7bc7fed483a2e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-14-10-34-00.bpo-33936.8wCI_n.rst +++ /dev/null @@ -1,2 +0,0 @@ -_hashlib no longer calls obsolete OpenSSL initialization function with -OpenSSL 1.1.0+. diff --git a/Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rs= t b/Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst deleted file mode 100644 index 6d9f280bbd050..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-15-10-30-33.bpo-38175.61XlUv.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a memory leak in comparison of :class:`sqlite3.Row` objects. diff --git a/Misc/NEWS.d/next/Library/2019-09-15-21-31-18.bpo-37828.gLLDX7.rs= t b/Misc/NEWS.d/next/Library/2019-09-15-21-31-18.bpo-37828.gLLDX7.rst deleted file mode 100644 index c364009b24086..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-15-21-31-18.bpo-37828.gLLDX7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix default mock name in :meth:`unittest.mock.Mock.assert_called` exceptions. -Patch by Abraham Toriz Cruz. diff --git a/Misc/NEWS.d/next/Library/2019-09-16-09-54-42.bpo-38136.MdI-Zb.rs= t b/Misc/NEWS.d/next/Library/2019-09-16-09-54-42.bpo-38136.MdI-Zb.rst deleted file mode 100644 index 78cad245e67d4..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-16-09-54-42.bpo-38136.MdI-Zb.rst +++ /dev/null @@ -1,3 +0,0 @@ -Changes AsyncMock call count and await count to be two different counters. -Now await count only counts when a coroutine has been awaited, not when it -has been called, and vice-versa. Update the documentation around this. diff --git a/Misc/NEWS.d/next/Library/2019-09-16-19-12-57.bpo-38185.zYWppY.rs= t b/Misc/NEWS.d/next/Library/2019-09-16-19-12-57.bpo-38185.zYWppY.rst deleted file mode 100644 index 2260db68e8cf7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-16-19-12-57.bpo-38185.zYWppY.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed case-insensitive string comparison in :class:`sqlite3.Row` indexing. diff --git a/Misc/NEWS.d/next/Library/2019-09-16-21-47-48.bpo-38155.d92lRc.rs= t b/Misc/NEWS.d/next/Library/2019-09-16-21-47-48.bpo-38155.d92lRc.rst deleted file mode 100644 index 14b6e2da67f98..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-16-21-47-48.bpo-38155.d92lRc.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``__all__`` to :mod:`datetime`. Patch by Tahia Khan. diff --git a/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rs= t b/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst deleted file mode 100644 index 05c7daaeafbed..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-17-12-28-27.bpo-38191.1TU0HV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Constructors of :class:`~typing.NamedTuple` and :class:`~typing.TypedDict` -types now accept arbitrary keyword argument names, including "cls", "self", -"typename", "_typename", "fields" and "_fields". diff --git a/Misc/NEWS.d/next/Library/2019-09-19-19-58-33.bpo-34002.KBnaVX.rs= t b/Misc/NEWS.d/next/Library/2019-09-19-19-58-33.bpo-34002.KBnaVX.rst deleted file mode 100644 index 5d4c231c74c62..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-19-19-58-33.bpo-34002.KBnaVX.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve efficiency in parts of email package by changing while-pop to a for -loop, using isdisjoint instead of set intersections. diff --git a/Misc/NEWS.d/next/Library/2019-09-20-14-27-17.bpo-38237.xRUZbx.rs= t b/Misc/NEWS.d/next/Library/2019-09-20-14-27-17.bpo-38237.xRUZbx.rst deleted file mode 100644 index 07e1bf712db34..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-20-14-27-17.bpo-38237.xRUZbx.rst +++ /dev/null @@ -1,2 +0,0 @@ -The arguments for the builtin pow function are more descriptive. They can now -also be passed in as keywords. diff --git a/Misc/NEWS.d/next/Library/2019-09-22-13-05-36.bpo-38248.Yo3N_1.rs= t b/Misc/NEWS.d/next/Library/2019-09-22-13-05-36.bpo-38248.Yo3N_1.rst deleted file mode 100644 index fc92209af3875..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-22-13-05-36.bpo-38248.Yo3N_1.rst +++ /dev/null @@ -1 +0,0 @@ -asyncio: Fix inconsistent immediate Task cancellation diff --git a/Misc/NEWS.d/next/Library/2019-09-24-10-55-01.bpo-38112.2EinX9.rs= t b/Misc/NEWS.d/next/Library/2019-09-24-10-55-01.bpo-38112.2EinX9.rst deleted file mode 100644 index ea49898de8d8e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-24-10-55-01.bpo-38112.2EinX9.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`compileall` has a higher default recursion limit and new command-line -arguments for path manipulation, symlinks handling, and multiple -optimization levels. diff --git a/Misc/NEWS.d/next/Library/2019-09-25-05-16-19.bpo-38265.X6-gsT.rs= t b/Misc/NEWS.d/next/Library/2019-09-25-05-16-19.bpo-38265.X6-gsT.rst deleted file mode 100644 index bd69a26149d1c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-25-05-16-19.bpo-38265.X6-gsT.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update the *length* parameter of :func:`os.pread` to accept -:c:type:`Py_ssize_t` instead of :c:type:`int`. diff --git a/Misc/NEWS.d/next/Library/2019-09-25-21-37-02.bpo-38108.Jr9HU6.rs= t b/Misc/NEWS.d/next/Library/2019-09-25-21-37-02.bpo-38108.Jr9HU6.rst deleted file mode 100644 index d7eea367e482b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-25-21-37-02.bpo-38108.Jr9HU6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Any synchronous magic methods on an AsyncMock now return a MagicMock. Any -asynchronous magic methods on a MagicMock now return an AsyncMock. diff --git a/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rs= t b/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst deleted file mode 100644 index ee9721587eeb9..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-26-12-16-30.bpo-28286.LdSsrN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate opening :class:`~gzip.GzipFile` for writing implicitly. Always -specify the *mode* argument for writing. diff --git a/Misc/NEWS.d/next/Library/2019-09-27-15-24-45.bpo-38216.-7yvZR.rs= t b/Misc/NEWS.d/next/Library/2019-09-27-15-24-45.bpo-38216.-7yvZR.rst deleted file mode 100644 index ac8e2b042d929..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-27-15-24-45.bpo-38216.-7yvZR.rst +++ /dev/null @@ -1,4 +0,0 @@ -Allow the rare code that wants to send invalid http requests from the -`http.client` library a way to do so. The fixes for bpo-30458 led to -breakage for some projects that were relying on this ability to test their -own behavior in the face of bad requests. diff --git a/Misc/NEWS.d/next/Library/2019-09-27-16-31-28.bpo-38161.zehai1.rs= t b/Misc/NEWS.d/next/Library/2019-09-27-16-31-28.bpo-38161.zehai1.rst deleted file mode 100644 index 0077033c654f5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-27-16-31-28.bpo-38161.zehai1.rst +++ /dev/null @@ -1 +0,0 @@ -Removes _AwaitEvent from AsyncMock. diff --git a/Misc/NEWS.d/next/Library/2019-09-28-20-16-40.bpo-38163.x51-vK.rs= t b/Misc/NEWS.d/next/Library/2019-09-28-20-16-40.bpo-38163.x51-vK.rst deleted file mode 100644 index 5f7db26e05ce9..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-28-20-16-40.bpo-38163.x51-vK.rst +++ /dev/null @@ -1,4 +0,0 @@ -Child mocks will now detect their type as either synchronous or -asynchronous, asynchronous child mocks will be AsyncMocks and synchronous -child mocks will be either MagicMock or Mock (depending on their parent -type). diff --git a/Misc/NEWS.d/next/Library/2019-09-29-13-50-24.bpo-38019.6MoOE3.rs= t b/Misc/NEWS.d/next/Library/2019-09-29-13-50-24.bpo-38019.6MoOE3.rst deleted file mode 100644 index aa5a23de24609..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-29-13-50-24.bpo-38019.6MoOE3.rst +++ /dev/null @@ -1 +0,0 @@ -Correctly handle pause/resume reading of closed asyncio unix pipe. diff --git a/Misc/NEWS.d/next/Library/2019-09-29-22-47-37.bpo-13153.0mO9qR.rs= t b/Misc/NEWS.d/next/Library/2019-09-29-22-47-37.bpo-13153.0mO9qR.rst deleted file mode 100644 index 6f9561539d8d3..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-29-22-47-37.bpo-13153.0mO9qR.rst +++ /dev/null @@ -1,4 +0,0 @@ -OS native encoding is now used for converting between Python strings and -Tcl objects. This allows to display, copy and paste to clipboard emoji and -other non-BMP characters. Converting strings from Tcl to Python and back -now never fails (except MemoryError). diff --git a/Misc/NEWS.d/next/Library/2019-09-30-00-15-27.bpo-38242.uPIyAc.rs= t b/Misc/NEWS.d/next/Library/2019-09-30-00-15-27.bpo-38242.uPIyAc.rst deleted file mode 100644 index be9da891b866f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-30-00-15-27.bpo-38242.uPIyAc.rst +++ /dev/null @@ -1 +0,0 @@ -Revert the new asyncio Streams API diff --git a/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rs= t b/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst deleted file mode 100644 index 376a9e459de27..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-09-30-22-06-33.bpo-38319.5QjiDa.rst +++ /dev/null @@ -1,2 +0,0 @@ -sendfile() used in socket and shutil modules was raising OverflowError for -files >=3D 2GiB on 32-bit architectures. (patch by Giampaolo Rodola) diff --git a/Misc/NEWS.d/next/Library/2019-10-01-21-06-18.bpo-38341.uqwgU_.rs= t b/Misc/NEWS.d/next/Library/2019-10-01-21-06-18.bpo-38341.uqwgU_.rst deleted file mode 100644 index dd1a6b080b627..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-01-21-06-18.bpo-38341.uqwgU_.rst +++ /dev/null @@ -1 +0,0 @@ -Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` exported name= s. diff --git a/Misc/NEWS.d/next/Library/2019-10-04-18-39-59.bpo-38371.S6Klvm.rs= t b/Misc/NEWS.d/next/Library/2019-10-04-18-39-59.bpo-38371.S6Klvm.rst deleted file mode 100644 index 583399531acd1..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-04-18-39-59.bpo-38371.S6Klvm.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecated the ``split()`` method in :class:`_tkinter.TkappType` in favour -of the ``splitlist()`` method which has more consistent and predicable -behavior. diff --git a/Misc/NEWS.d/next/Library/2019-10-05-02-07-52.bpo-38332.hwrPN7.rs= t b/Misc/NEWS.d/next/Library/2019-10-05-02-07-52.bpo-38332.hwrPN7.rst deleted file mode 100644 index 600c702cf3bbd..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-05-02-07-52.bpo-38332.hwrPN7.rst +++ /dev/null @@ -1,3 +0,0 @@ -Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` when given -an encoded-word with invalid content-type encoding from propagating all the -way to :func:`email.message.get`. diff --git a/Misc/NEWS.d/next/Library/2019-10-08-11-18-40.bpo-38405.0-7e7s.rs= t b/Misc/NEWS.d/next/Library/2019-10-08-11-18-40.bpo-38405.0-7e7s.rst deleted file mode 100644 index ee346a30ec416..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-08-11-18-40.bpo-38405.0-7e7s.rst +++ /dev/null @@ -1 +0,0 @@ -Nested subclasses of :class:`typing.NamedTuple` are now pickleable. diff --git a/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rs= t b/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst deleted file mode 100644 index 0958fe265db56..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-09-18-16-51.bpo-38422.aiM5bq.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify docstrings of pathlib suffix(es) diff --git a/Misc/NEWS.d/next/Library/2019-10-10-00-25-28.bpo-38109.9w-IGF.rs= t b/Misc/NEWS.d/next/Library/2019-10-10-00-25-28.bpo-38109.9w-IGF.rst deleted file mode 100644 index 3f4484dc644fa..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-10-00-25-28.bpo-38109.9w-IGF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add missing :data:`stat.S_IFDOOR`, :data:`stat.S_IFPORT`, :data:`stat.S_IFWH= T`, -:func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and :func:`stat.S_ISWHT` value= s to -the Python implementation of :mod:`stat`. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-10-10-16-53-00.bpo-38431.d5wzNp.rs= t b/Misc/NEWS.d/next/Library/2019-10-10-16-53-00.bpo-38431.d5wzNp.rst deleted file mode 100644 index c2f860d804c13..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-10-16-53-00.bpo-38431.d5wzNp.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``__repr__`` method for :class:`dataclasses.InitVar` to support typing o= bjects, patch by Samuel Colvin. diff --git a/Misc/NEWS.d/next/Library/2019-10-11-18-49-00.bpo-38449.9TWMlz.rs= t b/Misc/NEWS.d/next/Library/2019-10-11-18-49-00.bpo-38449.9TWMlz.rst deleted file mode 100644 index f7b1dbf8d8951..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-11-18-49-00.bpo-38449.9TWMlz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Revert GH-15522, which introduces a regression in -:meth:`mimetypes.guess_type` due to improper handling of filenames as urls. diff --git a/Misc/NEWS.d/next/Library/2019-10-12-00-13-47.bpo-38417.W7x_aS.rs= t b/Misc/NEWS.d/next/Library/2019-10-12-00-13-47.bpo-38417.W7x_aS.rst deleted file mode 100644 index c2356ddbf140f..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-12-00-13-47.bpo-38417.W7x_aS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added support for setting the umask in the child process to the subprocess -module on POSIX systems. diff --git a/Misc/NEWS.d/next/Library/2019-10-13-11-00-03.bpo-38378.yYNpSm.rs= t b/Misc/NEWS.d/next/Library/2019-10-13-11-00-03.bpo-38378.yYNpSm.rst deleted file mode 100644 index 1bc52825ee9b5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-13-11-00-03.bpo-38378.yYNpSm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Parameters *out* and *in* of :func:`os.sendfile` was renamed to *out_fd* and -*in_fd*. diff --git a/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rs= t b/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst deleted file mode 100644 index fbd73003cfcb6..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-15-09-47-40.bpo-33604.J12cWT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed `hmac.new` and `hmac.HMAC` to raise TypeError instead of ValueError -when the digestmod parameter, now required in 3.8, is omitted. Also -clarified the hmac module documentation and docstrings. diff --git a/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rs= t b/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst deleted file mode 100644 index b19fa23639d88..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-15-11-37-57.bpo-38478.A87OPO.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a bug in :meth:`inspect.signature.bind` that was causing it to fail -when handling a keyword argument with same name as positional-only parameter. -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Library/2019-10-16-19-56-51.bpo-38493.86ExWB.rs= t b/Misc/NEWS.d/next/Library/2019-10-16-19-56-51.bpo-38493.86ExWB.rst deleted file mode 100644 index 1a4bef65d4318..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-16-19-56-51.bpo-38493.86ExWB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rs= t b/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst deleted file mode 100644 index 9335bdc9545c4..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-18-13-57-31.bpo-38521.U-7aaM.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed erroneous equality comparison in statistics.NormalDist(). diff --git a/Misc/NEWS.d/next/Library/2019-10-19-21-41-20.bpo-36321.CFlxfy.rs= t b/Misc/NEWS.d/next/Library/2019-10-19-21-41-20.bpo-36321.CFlxfy.rst deleted file mode 100644 index cf51d71da17fa..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-19-21-41-20.bpo-36321.CFlxfy.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove misspelled attribute. The 3.8 changelog noted that this would be -removed in 3.9. diff --git a/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rs= t b/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst deleted file mode 100644 index 8edb09d61317b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst +++ /dev/null @@ -1,2 +0,0 @@ -The case the result of :func:`pathlib.WindowsPath.glob` matches now the case -of the pattern for literal parts. diff --git a/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rs= t b/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst deleted file mode 100644 index 34334db6032b5..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-23-16-25-12.bpo-34679.Bnw8o3.rst +++ /dev/null @@ -1,2 +0,0 @@ -asynci.ProactorEventLoop.close() now only calls signal.set_wakeup_fd() in the -main thread. diff --git a/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rs= t b/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst deleted file mode 100644 index 34d7afcf36df6..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-24-08-10-30.bpo-38565.SWSUst.rst +++ /dev/null @@ -1 +0,0 @@ -Add new cache_parameters() method for functools.lru_cache() to better suppor= t pickling. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-10-24-17-26-39.bpo-38586.cyq5nr.rs= t b/Misc/NEWS.d/next/Library/2019-10-24-17-26-39.bpo-38586.cyq5nr.rst deleted file mode 100644 index eac7bba082566..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-24-17-26-39.bpo-38586.cyq5nr.rst +++ /dev/null @@ -1 +0,0 @@ -Now :func:`~logging.config.fileConfig` correcty sets the .name of handlers l= oaded. diff --git a/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rs= t b/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst deleted file mode 100644 index 2a1800fd2b00d..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-26-14-42-20.bpo-38312.e_FVWh.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, -:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions - -by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-10-27-00-08-49.bpo-38334.pfLLmc.rs= t b/Misc/NEWS.d/next/Library/2019-10-27-00-08-49.bpo-38334.pfLLmc.rst deleted file mode 100644 index 0d05d3f6e6c09..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-27-00-08-49.bpo-38334.pfLLmc.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed seeking backward on an encrypted :class:`zipfile.ZipExtFile`. diff --git a/Misc/NEWS.d/next/Library/2019-10-27-22-29-45.bpo-38602.7jvYFA.rs= t b/Misc/NEWS.d/next/Library/2019-10-27-22-29-45.bpo-38602.7jvYFA.rst deleted file mode 100644 index 9b8229b4a024c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-10-27-22-29-45.bpo-38602.7jvYFA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added constants :data:`~fcntl.F_OFD_GETLK`, :data:`~fcntl.F_OFD_SETLK` -and :data:`~fcntl.F_OFD_SETLKW` to the :mod:`fcntl` module. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rs= t b/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst deleted file mode 100644 index fd19c6f9eb52e..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-05-07-18-24.bpo-38692.UpatA7.rst +++ /dev/null @@ -1 +0,0 @@ -Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`. diff --git a/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rs= t b/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst deleted file mode 100644 index 7c8b3e8d74ee7..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-05-19-15-57.bpo-38692.2DCDA-.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher -implementation that polls process file descriptors. diff --git a/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rs= t b/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst deleted file mode 100644 index a22719753d7f8..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-05-21-22-22.bpo-38713.bmhquU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :data:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to -wait on a Linux process file descriptor. diff --git a/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rs= t b/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst deleted file mode 100644 index 906eb6b6cd60a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-06-15-58-07.bpo-38716.R3uMLT.rst +++ /dev/null @@ -1 +0,0 @@ -logging: change RotatingHandler namer and rotator to class-level attributes.= This stops __init__ from setting them to None in the case where a subclass d= efines them with eponymous methods. diff --git a/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rs= t b/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst deleted file mode 100644 index 4dde5ebc3208c..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-10-13-40-33.bpo-38761.P1UUIZ.rst +++ /dev/null @@ -1 +0,0 @@ -WeakSet is now registered as a collections.abc.MutableSet. diff --git a/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rs= t b/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst deleted file mode 100644 index 69ea2de02f73a..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-11-06-14-25.bpo-38438.vSVeHN.rst +++ /dev/null @@ -1 +0,0 @@ -Simplify the :mod:`argparse` usage message for ``nargs=3D"*"``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rs= t b/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst deleted file mode 100644 index 37be6a5d0b22b..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-11-21-43-06.bpo-27805.D3zl1_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow opening pipes and other non-seekable files in append mode with -:func:`open`. diff --git a/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rs= t b/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst deleted file mode 100644 index c84bb8589d303..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-12-15-46-28.bpo-38723.gcdMFn.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`pdb` now uses :meth:`io.open_code` to trigger auditing events. diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rs= t b/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst deleted file mode 100644 index 49e9937998081..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-13-16-17-43.bpo-38785.NEOEfk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent asyncio from crashing if parent ``__init__`` is not called from a -constructor of object derived from ``asyncio.Future``. diff --git a/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rs= t b/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst deleted file mode 100644 index f95d773e08c50..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-13-16-49-03.bpo-38786.gNOwKh.rst +++ /dev/null @@ -1 +0,0 @@ -pydoc now recognizes and parses HTTPS URLs. Patch by python273. diff --git a/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rs= t b/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst deleted file mode 100644 index a5ebfb3322999..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-14-14-13-29.bpo-38724.T5ySfR.rst +++ /dev/null @@ -1 +0,0 @@ -Add a repr for ``subprocess.Popen`` objects. Patch by Andrey Doroschenko. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rs= t b/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst deleted file mode 100644 index 2bd7e3deb19ed..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-15-09-30-29.bpo-38807.PsmRog.rst +++ /dev/null @@ -1 +0,0 @@ -Update :exc:`TypeError` messages for :meth:`os.path.join` to include :class:= `os.PathLike` objects as acceptable input types. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rs= t b/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst deleted file mode 100644 index 3c1221b203494..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-11-16-22-56-51.bpo-36589.0Io76D.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :func:`curses.update_lines_cols` function now returns ``None`` instead -of ``1`` on success. diff --git a/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.r= st b/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst deleted file mode 100644 index 50292e29ed1d2..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst +++ /dev/null @@ -1 +0,0 @@ -Fix parsing of invalid email addresses with more than one ``@`` (e.g. a at b@c.= com.) to not return the part before 2nd ``@`` as valid email address. Patch b= y maxking & jpic. diff --git a/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.r= st b/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst deleted file mode 100644 index 90aa30192fc8c..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-17-09-34-25.bpo-34631.DBfM4j.rst +++ /dev/null @@ -1 +0,0 @@ -Updated OpenSSL to 1.1.1c in Windows installer diff --git a/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.r= st b/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst deleted file mode 100644 index 7506fa9064b12..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-21-14-42-53.bpo-37364.IIRc2s.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`io.open_code` is now used when reading :file:`.pth` files. diff --git a/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.r= st b/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst deleted file mode 100644 index 1b724ff559e28..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-06-21-15-58-59.bpo-37363.diouyl.rst +++ /dev/null @@ -1,5 +0,0 @@ -Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, -:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, -:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, -:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, -:func:`os.scandir` and :func:`breakpoint`. diff --git a/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.r= st b/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst deleted file mode 100644 index 4f4a62e783746..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-07-01-08-46-14.bpo-37463.1CHwjE.rst +++ /dev/null @@ -1,4 +0,0 @@ -ssl.match_hostname() no longer accepts IPv4 addresses with additional text -after the address and only quad-dotted notation without trailing -whitespaces. Some inet_aton() implementations ignore whitespace and all data -after whitespace, e.g. '127.0.0.1 whatever'. diff --git a/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.r= st b/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst deleted file mode 100644 index a8bde90db4967..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-07-01-10-31-14.bpo-37363.fSjatj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adds audit events for the range of supported run commands (see -:ref:`using-on-general`). diff --git a/Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.r= st b/Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst deleted file mode 100644 index 9d47578c62771..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an infinite loop when parsing specially crafted email headers. Patch by -Abhilash Raj. diff --git a/Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.r= st b/Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.rst deleted file mode 100644 index 27fa8e192f0c0..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes email._header_value_parser.get_unstructured going into an infinite loo= p for a specific case in which the email header does not have trailing whites= pace, and the case in which it contains an invalid encoded word. Patch by Ash= win Ramaswami. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Security/2019-09-23-21-02-46.bpo-38174.MeWuJd.r= st b/Misc/NEWS.d/next/Security/2019-09-23-21-02-46.bpo-38174.MeWuJd.rst deleted file mode 100644 index e3da6fcdd139f..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-09-23-21-02-46.bpo-38174.MeWuJd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update vendorized expat library version to 2.2.8, which resolves -CVE-2019-15903. diff --git a/Misc/NEWS.d/next/Security/2019-09-25-13-21-09.bpo-38243.1pfz24.r= st b/Misc/NEWS.d/next/Security/2019-09-25-13-21-09.bpo-38243.1pfz24.rst deleted file mode 100644 index 98d7be129573a..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-09-25-13-21-09.bpo-38243.1pfz24.rst +++ /dev/null @@ -1,3 +0,0 @@ -Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` -when rendering the document page as HTML. -(Contributed by Dong-hee Na in :issue:`38243`.) diff --git a/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.r= st b/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst deleted file mode 100644 index b42a00047b96c..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-10-08-19-29-55.bpo-38418.QL7s0-.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes audit event for :func:`os.system` to be named ``os.system``. diff --git a/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.r= st b/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst deleted file mode 100644 index 0373c14d0a1cd..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-11-14-16-13-23.bpo-38622.3DYkfb.rst +++ /dev/null @@ -1 +0,0 @@ -Add additional audit events for the :mod:`ctypes` module. diff --git a/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.r= st b/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst deleted file mode 100644 index 0277d3e5689a2..0000000000000 --- a/Misc/NEWS.d/next/Security/2019-11-18-16-17-56.bpo-38722.x3mECW.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`runpy` now uses :meth:`io.open_code` to open code files. -Patch by Jason Killen. diff --git a/Misc/NEWS.d/next/Tests/2018-09-07-01-18-27.bpo-34596.r2-EGd.rst = b/Misc/NEWS.d/next/Tests/2018-09-07-01-18-27.bpo-34596.r2-EGd.rst deleted file mode 100644 index 156e8aa8945de..0000000000000 --- a/Misc/NEWS.d/next/Tests/2018-09-07-01-18-27.bpo-34596.r2-EGd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fallback to a default reason when :func:`unittest.skip` is uncalled. Patch by -Naitree Zhu. diff --git a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst = b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst deleted file mode 100644 index 233640716d152..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst +++ /dev/null @@ -1,3 +0,0 @@ -Modify the test_uuid logic to test when a program is available -AND can be used to obtain a MACADDR as basis for an UUID. -Patch by M. Felt diff --git a/Misc/NEWS.d/next/Tests/2019-04-15-19-05-35.bpo-30202.Wt7INj.rst = b/Misc/NEWS.d/next/Tests/2019-04-15-19-05-35.bpo-30202.Wt7INj.rst deleted file mode 100644 index 29fae778fba78..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-04-15-19-05-35.bpo-30202.Wt7INj.rst +++ /dev/null @@ -1 +0,0 @@ -Update ``test.test_importlib.test_abc`` to test ``find_spec()``. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-05-28-15-41-34.bpo-36919.-vGt_m.rst = b/Misc/NEWS.d/next/Tests/2019-05-28-15-41-34.bpo-36919.-vGt_m.rst deleted file mode 100644 index 9400bdda5da18..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-28-15-41-34.bpo-36919.-vGt_m.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make ``test_source_encoding.test_issue2301`` implementation independent. The -test will work now for both CPython and IronPython. diff --git a/Misc/NEWS.d/next/Tests/2019-06-03-20-47-10.bpo-34001.KvYx9z.rst = b/Misc/NEWS.d/next/Tests/2019-06-03-20-47-10.bpo-34001.KvYx9z.rst deleted file mode 100644 index 35c65a8fbf0fa..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-03-20-47-10.bpo-34001.KvYx9z.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make test_ssl pass with LibreSSL. LibreSSL handles minimum and maximum TLS -version differently than OpenSSL. diff --git a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst = b/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst deleted file mode 100644 index 706ebaa20b7c6..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst +++ /dev/null @@ -1,2 +0,0 @@ -``test_venv.test_multiprocessing()`` now explicitly calls -``pool.terminate()`` to wait until the pool completes. diff --git a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst = b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst deleted file mode 100644 index f2f0a8b8d8ea2..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst +++ /dev/null @@ -1 +0,0 @@ -Rewrite ``_PyObject_IsFreed()`` unit tests. diff --git a/Misc/NEWS.d/next/Tests/2019-06-12-14-30-29.bpo-37252.4o-uLs.rst = b/Misc/NEWS.d/next/Tests/2019-06-12-14-30-29.bpo-37252.4o-uLs.rst deleted file mode 100644 index 1bd7d2872f13b..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-12-14-30-29.bpo-37252.4o-uLs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix assertions in ``test_close`` and ``test_events_mask_overflow`` devpoll -tests. diff --git a/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst = b/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst deleted file mode 100644 index f9f6474ac8cfd..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst +++ /dev/null @@ -1,7 +0,0 @@ -regrtest now uses :func:`sys.unraisablehook` to mark a test as "environment -altered" (ENV_CHANGED) if it emits an "unraisable exception". Moreover, -regrtest logs a warning in this case. - -Use ``python3 -m test --fail-env-changed`` to catch unraisable exceptions in -tests. - diff --git a/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst = b/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst deleted file mode 100644 index 27ce78a70f2bf..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method -now ignores unraisable exception raised when clearing its ``unraisable`` -attribute. diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst = b/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst deleted file mode 100644 index 3d3011b51c5b1..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a -running thread and leaking a reference. diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst = b/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst deleted file mode 100644 index 23b6d00f42c5b..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst +++ /dev/null @@ -1 +0,0 @@ -Avoid TimeoutError in test_asyncio: test_start_tls_server_1() diff --git a/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst = b/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst deleted file mode 100644 index 43fdc1030c575..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-21-15-47-33.bpo-37362.D3xppx.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_gdb no longer fails if it gets an "unexpected" message on stderr: it now -ignores stderr. The purpose of test_gdb is to test that python-gdb.py comman= ds -work as expected, not to test gdb. diff --git a/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst = b/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst deleted file mode 100644 index 3d5350de4f43f..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-24-10-47-07.bpo-37359.CkdtyO.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add --cleanup option to python3 -m test to remove ``test_python_*`` -directories of previous failed jobs. Add "make cleantest" to run -``python3 -m test --cleanup``. - diff --git a/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst = b/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst deleted file mode 100644 index 737c781890099..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-25-16-02-43.bpo-37400.cx_EWv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() -to get groups. Rename also the test to test_chown_gid(). diff --git a/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst = b/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst deleted file mode 100644 index 20e52d3c74f72..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-26-15-28-45.bpo-37411.5lGNhM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_wsgiref.testEnviron() to no longer depend on the environment -variables (don't fail if "X" variable is set). diff --git a/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst = b/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst deleted file mode 100644 index 9f4033831d68a..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-27-00-37-59.bpo-37421.rVJb3x.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_shutil to no longer leak temporary files. diff --git a/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst = b/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst deleted file mode 100644 index cb884d926590c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-28-16-37-52.bpo-37335.o5S2hY.rst +++ /dev/null @@ -1 +0,0 @@ -Remove no longer necessary code from c locale coercion tests diff --git a/Misc/NEWS.d/next/Tests/2019-06-29-16-02-21.bpo-19696.05ijhN.rst = b/Misc/NEWS.d/next/Tests/2019-06-29-16-02-21.bpo-19696.05ijhN.rst deleted file mode 100644 index c029fb9f6fc1f..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-29-16-02-21.bpo-19696.05ijhN.rst +++ /dev/null @@ -1 +0,0 @@ -Replace deprecated method "random.choose" with "random.choice" in "test_pkg_= import.py". \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst = b/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst deleted file mode 100644 index b05209159cc81..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-29-23-56-28.bpo-37199.FHDsLf.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test failures when IPv6 is unavailable or disabled. diff --git a/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst = b/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst deleted file mode 100644 index f62b5d54867fd..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-01-17-19-47.bpo-37472.WzkEAx.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``Lib/test/outstanding_bugs.py``. diff --git a/Misc/NEWS.d/next/Tests/2019-07-01-19-56-17.bpo-37421.bOe350.rst = b/Misc/NEWS.d/next/Tests/2019-07-01-19-56-17.bpo-37421.bOe350.rst deleted file mode 100644 index c89134fdb7fa6..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-01-19-56-17.bpo-37421.bOe350.rst +++ /dev/null @@ -1,4 +0,0 @@ -urllib.request tests now call :func:`~urllib.request.urlcleanup` to remove -temporary files created by ``urlretrieve()`` tests and to clear the ``_opene= r`` -global variable set by ``urlopen()`` and functions calling indirectly -``urlopen()``. diff --git a/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst = b/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst deleted file mode 100644 index c379b504ba8a4..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-01-19-57-26.bpo-37421.NFH1f0.rst +++ /dev/null @@ -1,2 +0,0 @@ -multiprocessing tests now explicitly call ``_run_finalizers()`` to -immediately remove temporary directories created by tests. diff --git a/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst = b/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst deleted file mode 100644 index 6671ffe922fda..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-02-23-20-35.bpo-37421.HCkKWz.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_winconsoleio doesn't leak a temporary file anymore: use -tempfile.TemporaryFile() to remove it when the test completes. diff --git a/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst = b/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst deleted file mode 100644 index 215a0a144459c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-02-23-29-06.bpo-37421.WEfc5A.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_concurrent_futures now cleans up multiprocessing to remove immediately -temporary directories created by multiprocessing.util.get_temp_dir(). diff --git a/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst = b/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst deleted file mode 100644 index 8610509e4b72b..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-03-00-05-28.bpo-37421.ORGRSG.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_distutils.test_build_ext() is now able to remove the temporary -directory on Windows: don't import the newly built C extension ("xx") in the -current process, but test it in a separated process. diff --git a/Misc/NEWS.d/next/Tests/2019-07-05-14-47-55.bpo-37421.n8o2to.rst = b/Misc/NEWS.d/next/Tests/2019-07-05-14-47-55.bpo-37421.n8o2to.rst deleted file mode 100644 index 136faa22d47a6..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-05-14-47-55.bpo-37421.n8o2to.rst +++ /dev/null @@ -1,3 +0,0 @@ -multiprocessing tests now stop the ForkServer instance if it's running: close -the "alive" file descriptor to ask the server to stop and then remove its UN= IX -address. diff --git a/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst = b/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst deleted file mode 100644 index 0766d70f6eda3..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-08-10-11-36.bpo-37421.OY77go.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_concurrent_futures now explicitly stops the ForkServer instance if it's -running. diff --git a/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst = b/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst deleted file mode 100644 index aff6b6d1f12c2..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-09-12-33-18.bpo-37526.vmm5y7.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`test.support.catch_threading_exception`: context manager catching -:class:`threading.Thread` exception using :func:`threading.excepthook`. diff --git a/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst = b/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst deleted file mode 100644 index 9f393d71a3f23..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-11-10-33-56.bpo-37558.SKHRsL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_shared_memory_cleaned_after_process_termination name handling diff --git a/Misc/NEWS.d/next/Tests/2019-07-18-14-52-58.bpo-36833.Zoe9ek.rst = b/Misc/NEWS.d/next/Tests/2019-07-18-14-52-58.bpo-36833.Zoe9ek.rst deleted file mode 100644 index 3632f98f34f02..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-07-18-14-52-58.bpo-36833.Zoe9ek.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of -the :mod:`datetime` module. Patch by Joannah Nanjekye. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-08-16-16-15-14.bpo-37876.m3k1w3.rst = b/Misc/NEWS.d/next/Tests/2019-08-16-16-15-14.bpo-37876.m3k1w3.rst deleted file mode 100644 index 45702fc635103..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-08-16-16-15-14.bpo-37876.m3k1w3.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for ROT-13 codec. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-08-20-19-24-19.bpo-37531.wRoXfU.rst = b/Misc/NEWS.d/next/Tests/2019-08-20-19-24-19.bpo-37531.wRoXfU.rst deleted file mode 100644 index 59500ce67a01e..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-08-20-19-24-19.bpo-37531.wRoXfU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Enhance regrtest multiprocess timeout: write a message when killing a worker -process, catch popen.kill() and popen.wait() exceptions, put a timeout on the -second call to popen.communicate(). diff --git a/Misc/NEWS.d/next/Tests/2019-08-25-19-51-46.bpo-37805.Kl1sti.rst = b/Misc/NEWS.d/next/Tests/2019-08-25-19-51-46.bpo-37805.Kl1sti.rst deleted file mode 100644 index 478c38c3d4c50..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-08-25-19-51-46.bpo-37805.Kl1sti.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for json.dump(..., skipkeys=3DTrue). Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Tests/2019-09-03-19-33-10.bpo-38018.zTrMu7.rst = b/Misc/NEWS.d/next/Tests/2019-09-03-19-33-10.bpo-38018.zTrMu7.rst deleted file mode 100644 index 3646404ae2824..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-03-19-33-10.bpo-38018.zTrMu7.rst +++ /dev/null @@ -1 +0,0 @@ -Increase code coverage for multiprocessing.shared_memory. diff --git a/Misc/NEWS.d/next/Tests/2019-09-11-17-22-32.bpo-38117.X7LgGY.rst = b/Misc/NEWS.d/next/Tests/2019-09-11-17-22-32.bpo-38117.X7LgGY.rst deleted file mode 100644 index d3280375516a0..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-11-17-22-32.bpo-38117.X7LgGY.rst +++ /dev/null @@ -1 +0,0 @@ -Test with OpenSSL 1.1.1d diff --git a/Misc/NEWS.d/next/Tests/2019-09-24-12-24-05.bpo-38212.IWbhWz.rst = b/Misc/NEWS.d/next/Tests/2019-09-24-12-24-05.bpo-38212.IWbhWz.rst deleted file mode 100644 index 83a812d469981..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-24-12-24-05.bpo-38212.IWbhWz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Multiprocessing tests: increase test_queue_feeder_donot_stop_onexc() timeout -from 1 to 60 seconds. diff --git a/Misc/NEWS.d/next/Tests/2019-09-24-12-30-55.bpo-37123.IoutBn.rst = b/Misc/NEWS.d/next/Tests/2019-09-24-12-30-55.bpo-37123.IoutBn.rst deleted file mode 100644 index 200a5c324d6de..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-24-12-30-55.bpo-37123.IoutBn.rst +++ /dev/null @@ -1,4 +0,0 @@ -Multiprocessing test test_mymanager() now also expects -SIGTERM, not only -exitcode 0. BaseManager._finalize_manager() sends SIGTERM to the manager -process if it takes longer than 1 second to stop, which happens on slow -buildbots. diff --git a/Misc/NEWS.d/next/Tests/2019-09-25-12-18-31.bpo-38270._x-9uH.rst = b/Misc/NEWS.d/next/Tests/2019-09-25-12-18-31.bpo-38270._x-9uH.rst deleted file mode 100644 index efb1b98b36d00..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-25-12-18-31.bpo-38270._x-9uH.rst +++ /dev/null @@ -1,4 +0,0 @@ -test.support now has a helper function to check for availibility of a -hash digest function. Several tests are refactored avoid MD5 and use -SHA256 instead. Other tests are marked to use MD5 and skipped when MD5 is -disabled. diff --git a/Misc/NEWS.d/next/Tests/2019-09-25-13-11-29.bpo-38271.iHXNIg.rst = b/Misc/NEWS.d/next/Tests/2019-09-25-13-11-29.bpo-38271.iHXNIg.rst deleted file mode 100644 index 8f43d321d371a..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-25-13-11-29.bpo-38271.iHXNIg.rst +++ /dev/null @@ -1,4 +0,0 @@ -The private keys for test_ssl were encrypted with 3DES in traditional -PKCS#5 format. 3DES and the digest algorithm of PKCS#5 are blocked by -some strict crypto policies. Use PKCS#8 format with AES256 encryption -instead. diff --git a/Misc/NEWS.d/next/Tests/2019-09-25-14-40-57.bpo-38275.-kdveI.rst = b/Misc/NEWS.d/next/Tests/2019-09-25-14-40-57.bpo-38275.-kdveI.rst deleted file mode 100644 index 893c0f137aeaf..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-25-14-40-57.bpo-38275.-kdveI.rst +++ /dev/null @@ -1,4 +0,0 @@ -test_ssl now handles disabled TLS/SSL versions better. OpenSSL's crypto -policy and run-time settings are recognized and tests for disabled versions -are skipped. Tests also accept more TLS minimum_versions for platforms that -override OpenSSL's default with strict settings. diff --git a/Misc/NEWS.d/next/Tests/2019-09-26-15-48-36.bpo-38239.MfoVzY.rst = b/Misc/NEWS.d/next/Tests/2019-09-26-15-48-36.bpo-38239.MfoVzY.rst deleted file mode 100644 index f79da29fa1828..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-09-26-15-48-36.bpo-38239.MfoVzY.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_gdb for Link Time Optimization (LTO) builds. diff --git a/Misc/NEWS.d/next/Tests/2019-10-08-16-42-05.bpo-37531.7v-_Ca.rst = b/Misc/NEWS.d/next/Tests/2019-10-08-16-42-05.bpo-37531.7v-_Ca.rst deleted file mode 100644 index 78ab636516514..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-08-16-42-05.bpo-37531.7v-_Ca.rst +++ /dev/null @@ -1,5 +0,0 @@ -On timeout, regrtest no longer attempts to call ``popen.communicate()`` -again: it can hang until all child processes using stdout and stderr pipes -completes. Kill the worker process and ignores its output. Change also the -faulthandler timeout of the main process from 1 minute to 5 minutes, for Pyt= hon -slowest buildbots. diff --git a/Misc/NEWS.d/next/Tests/2019-10-14-22-46-35.bpo-38470.NHtzpy.rst = b/Misc/NEWS.d/next/Tests/2019-10-14-22-46-35.bpo-38470.NHtzpy.rst deleted file mode 100644 index bb4710f86d4c8..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-14-22-46-35.bpo-38470.NHtzpy.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix ``test_compileall.test_compile_dir_maxlevels()`` on Windows without long -path support: only create 3 subdirectories instead of between 20 and 100 -subdirectories. diff --git a/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst = b/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst deleted file mode 100644 index 43d3942fd0772..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-16-01-36-15.bpo-35998.G305Bf.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a race condition in test_asyncio.test_start_tls_server_1(). Previously, -there was a race condition between the test main() function which replaces t= he -protocol and the test ServerProto protocol which sends ANSWER once it gets -HELLO. Now, only the test main() function is responsible to send data, -ServerProto no longer sends data. diff --git a/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst = b/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst deleted file mode 100644 index 1df523e90c388..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-17-00-49-38.bpo-38502.vUEic7.rst +++ /dev/null @@ -1,3 +0,0 @@ -test.regrtest now uses process groups in the multiprocessing mode (-jN comma= nd -line option) if process groups are available: if :func:`os.setsid` and -:func:`os.killpg` functions are available. diff --git a/Misc/NEWS.d/next/Tests/2019-10-28-15-56-02.bpo-38614.aDdDYE.rst = b/Misc/NEWS.d/next/Tests/2019-10-28-15-56-02.bpo-38614.aDdDYE.rst deleted file mode 100644 index 42ff853a12be1..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-28-15-56-02.bpo-38614.aDdDYE.rst +++ /dev/null @@ -1,4 +0,0 @@ -Add timeout constants to :mod:`test.support`: -:data:`~test.support.LOOPBACK_TIMEOUT`, -:data:`~test.support.INTERNET_TIMEOUT`, :data:`~test.support.SHORT_TIMEOUT` -and :data:`~test.support.LONG_TIMEOUT`. diff --git a/Misc/NEWS.d/next/Tests/2019-10-30-15-12-32.bpo-38614.M6UnLB.rst = b/Misc/NEWS.d/next/Tests/2019-10-30-15-12-32.bpo-38614.M6UnLB.rst deleted file mode 100644 index 89f6847e689dd..0000000000000 --- a/Misc/NEWS.d/next/Tests/2019-10-30-15-12-32.bpo-38614.M6UnLB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix test_communicate() of test_asyncio.test_subprocess: use -``support.LONG_TIMEOUT`` (5 minutes), instead of just 1 minute. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-05-27-15-26-12.bpo-37064.k_SPW= 2.rst b/Misc/NEWS.d/next/Tools-Demos/2019-05-27-15-26-12.bpo-37064.k_SPW2.rst deleted file mode 100644 index d1210e29532bc..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-05-27-15-26-12.bpo-37064.k_SPW2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add option -k to pathscript.py script: preserve shebang flags. -Add option -a to pathscript.py script: add flags. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-05-27-16-13-08.bpo-37034.zbTgy= 8.rst b/Misc/NEWS.d/next/Tools-Demos/2019-05-27-16-13-08.bpo-37034.zbTgy8.rst deleted file mode 100644 index 3457789635b4e..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-05-27-16-13-08.bpo-37034.zbTgy8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Argument Clinic now uses the argument name on errors with keyword-only -argument instead of their position. Patch contributed by R=C3=A9mi Lapeyre. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-07-24-16-20-54.bpo-37675.951Cv= f.rst b/Misc/NEWS.d/next/Tools-Demos/2019-07-24-16-20-54.bpo-37675.951Cvf.rst deleted file mode 100644 index e28fa207f918a..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-07-24-16-20-54.bpo-37675.951Cvf.rst +++ /dev/null @@ -1 +0,0 @@ -2to3 now works when run from a zipped standard library. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-07-29-13-59-19.bpo-37704.xxGUz= _.rst b/Misc/NEWS.d/next/Tools-Demos/2019-07-29-13-59-19.bpo-37704.xxGUz_.rst deleted file mode 100644 index 52ca4895dee9e..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-07-29-13-59-19.bpo-37704.xxGUz_.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``Tools/scripts/h2py.py``: use cffi to access a C API in Python. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9= a.rst b/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst deleted file mode 100644 index 6f64314095545..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-08-24-12-11-30.bpo-37942.7H8N9a.rst +++ /dev/null @@ -1 +0,0 @@ -Improve ArgumentClinic converter for floats. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-09-12-16-15-55.bpo-37803.chEiz= y.rst b/Misc/NEWS.d/next/Tools-Demos/2019-09-12-16-15-55.bpo-37803.chEizy.rst deleted file mode 100644 index 5c0eedb937096..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-09-12-16-15-55.bpo-37803.chEizy.rst +++ /dev/null @@ -1 +0,0 @@ -pdb's ``--help`` and ``--version`` long options now work. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-10-02-09-48-42.bpo-38347.2Tq5D= 1.rst b/Misc/NEWS.d/next/Tools-Demos/2019-10-02-09-48-42.bpo-38347.2Tq5D1.rst deleted file mode 100644 index ae64a319b5756..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-10-02-09-48-42.bpo-38347.2Tq5D1.rst +++ /dev/null @@ -1 +0,0 @@ -pathfix.py: Assume all files that end on '.py' are Python scripts when worki= ng recursively. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-10-08-15-07-52.bpo-38118.pIZD6= H.rst b/Misc/NEWS.d/next/Tools-Demos/2019-10-08-15-07-52.bpo-38118.pIZD6H.rst deleted file mode 100644 index 13adadb0b8f7a..0000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-10-08-15-07-52.bpo-38118.pIZD6H.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update Valgrind suppression file to ignore a false alarm in -:c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). diff --git a/Misc/NEWS.d/next/Windows/2019-04-10-21-13-26.bpo-36590.ZTaKcu.rs= t b/Misc/NEWS.d/next/Windows/2019-04-10-21-13-26.bpo-36590.ZTaKcu.rst deleted file mode 100644 index 6a186bbeed74c..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-04-10-21-13-26.bpo-36590.ZTaKcu.rst +++ /dev/null @@ -1 +0,0 @@ -Add native Bluetooth RFCOMM support to socket module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2019-05-05-05-23-34.bpo-28269.-MOHI7.rs= t b/Misc/NEWS.d/next/Windows/2019-05-05-05-23-34.bpo-28269.-MOHI7.rst deleted file mode 100644 index a531b98118a23..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-05-05-05-23-34.bpo-28269.-MOHI7.rst +++ /dev/null @@ -1 +0,0 @@ -Replace use of :c:func:`strcasecmp` for the system function :c:func:`_stricm= p`. Patch by Minmin Gong. diff --git a/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rs= t b/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst deleted file mode 100644 index 41483aa8b74a9..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-05-10-15-25-44.bpo-32587.-0g2O3.rst +++ /dev/null @@ -1 +0,0 @@ -Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. diff --git a/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rs= t b/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst deleted file mode 100644 index 618cfcae7b899..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure ``time.tzname`` is correct on Windows when the active code page is -set to CP_UTF7 or CP_UTF8. diff --git a/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rs= t b/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst deleted file mode 100644 index a4dcfcde35b0d..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-13-04-15-51.bpo-37267.Ygo5ef.rst +++ /dev/null @@ -1,2 +0,0 @@ -On Windows, :func:`os.dup` no longer creates an inheritable fd when handling -a character file. diff --git a/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rs= t b/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst deleted file mode 100644 index 8fea56a00fdc0..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-18-09-05-08.bpo-35360.tdqSmo.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows builds to use SQLite 3.28.0. diff --git a/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rs= t b/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst deleted file mode 100644 index df2efd4a9a413..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-20-12-50-32.bpo-37351.asTnVW.rst +++ /dev/null @@ -1 +0,0 @@ -Removes libpython38.a from standard Windows distribution. diff --git a/Misc/NEWS.d/next/Windows/2019-06-25-04-15-22.bpo-37380.tPxjuz.rs= t b/Misc/NEWS.d/next/Windows/2019-06-25-04-15-22.bpo-37380.tPxjuz.rst deleted file mode 100644 index facce27954a63..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-25-04-15-22.bpo-37380.tPxjuz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Don't collect unfinished processes with ``subprocess._active`` on Windows to -cleanup later. Patch by Ruslan Kuprieiev. diff --git a/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rs= t b/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst deleted file mode 100644 index 5eaed61a9261b..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-28-09-44-08.bpo-37369.1iVpxq.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes path for :data:`sys.executable` when running from the Microsoft Store. diff --git a/Misc/NEWS.d/next/Windows/2019-06-28-18-10-29.bpo-37445.LsdYO6.rs= t b/Misc/NEWS.d/next/Windows/2019-06-28-18-10-29.bpo-37445.LsdYO6.rst deleted file mode 100644 index e4805b4e02fb1..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-06-28-18-10-29.bpo-37445.LsdYO6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in ``FormatMessageW()`` -calls. diff --git a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rs= t b/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst deleted file mode 100644 index d39576545efa4..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-07-01-12-38-48.bpo-10945.s0YBHG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Officially drop support for creating bdist_wininst installers on non-Windows -systems. diff --git a/Misc/NEWS.d/next/Windows/2019-07-24-14-36-28.bpo-37672.uKEVHN.rs= t b/Misc/NEWS.d/next/Windows/2019-07-24-14-36-28.bpo-37672.uKEVHN.rst deleted file mode 100644 index 78b51c191825b..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-07-24-14-36-28.bpo-37672.uKEVHN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Switch Windows Store package's pip to use bundled :file:`pip.ini` instead of -:envvar:`PIP_USER` variable. diff --git a/Misc/NEWS.d/next/Windows/2019-07-29-16-49-31.bpo-37702.Lj2f5e.rs= t b/Misc/NEWS.d/next/Windows/2019-07-29-16-49-31.bpo-37702.Lj2f5e.rst deleted file mode 100644 index 67d53d4c46276..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-07-29-16-49-31.bpo-37702.Lj2f5e.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix memory leak on Windows in creating an SSLContext object or -running urllib.request.urlopen('https://...'). \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2019-08-06-09-35-12.bpo-37734.EoJ9Nh.rs= t b/Misc/NEWS.d/next/Windows/2019-08-06-09-35-12.bpo-37734.EoJ9Nh.rst deleted file mode 100644 index 51feecb076bae..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-06-09-35-12.bpo-37734.EoJ9Nh.rst +++ /dev/null @@ -1 +0,0 @@ -Fix use of registry values to launch Python from Microsoft Store app. diff --git a/Misc/NEWS.d/next/Windows/2019-08-06-13-54-12.bpo-37778.AY1XhH.rs= t b/Misc/NEWS.d/next/Windows/2019-08-06-13-54-12.bpo-37778.AY1XhH.rst deleted file mode 100644 index 14d81c05ee846..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-06-13-54-12.bpo-37778.AY1XhH.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes the icons used for file associations to the Microsoft Store package. diff --git a/Misc/NEWS.d/next/Windows/2019-08-06-18-09-18.bpo-25172.Akreij.rs= t b/Misc/NEWS.d/next/Windows/2019-08-06-18-09-18.bpo-25172.Akreij.rst deleted file mode 100644 index 47106d8879217..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-06-18-09-18.bpo-25172.Akreij.rst +++ /dev/null @@ -1 +0,0 @@ -Trying to import the :mod:`crypt` module on Windows will result in an :exc:`= ImportError` with a message explaining that the module isn't supported on Win= dows. On other platforms, if the underlying ``_crypt`` module is not availabl= e, the ImportError will include a message explaining the problem. diff --git a/Misc/NEWS.d/next/Windows/2019-08-08-18-05-27.bpo-36266.x4eZU3.rs= t b/Misc/NEWS.d/next/Windows/2019-08-08-18-05-27.bpo-36266.x4eZU3.rst deleted file mode 100644 index 86fdd6fe17f41..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-08-18-05-27.bpo-36266.x4eZU3.rst +++ /dev/null @@ -1 +0,0 @@ -Add the module name in the formatted error message when DLL load fail happen= s during module import in ``_PyImport_FindSharedFuncptrWindows()``. Patch by = Srinivas Nyayapati. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2019-08-12-12-00-24.bpo-37834.VB2QVj.rs= t b/Misc/NEWS.d/next/Windows/2019-08-12-12-00-24.bpo-37834.VB2QVj.rst deleted file mode 100644 index f2a654cac9118..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-12-12-00-24.bpo-37834.VB2QVj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Treat all name surrogate reparse points on Windows in :func:`os.lstat` and -other reparse points as regular files in :func:`os.stat`. diff --git a/Misc/NEWS.d/next/Windows/2019-08-14-13-40-15.bpo-9949.zW45Ks.rst= b/Misc/NEWS.d/next/Windows/2019-08-14-13-40-15.bpo-9949.zW45Ks.rst deleted file mode 100644 index e42169a927c71..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-14-13-40-15.bpo-9949.zW45Ks.rst +++ /dev/null @@ -1 +0,0 @@ -Enable support for following symlinks in :func:`os.realpath`. diff --git a/Misc/NEWS.d/next/Windows/2019-08-21-12-58-18.bpo-1311.BoW1wU.rst= b/Misc/NEWS.d/next/Windows/2019-08-21-12-58-18.bpo-1311.BoW1wU.rst deleted file mode 100644 index 2ee98e450fae8..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-21-12-58-18.bpo-1311.BoW1wU.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``nul`` file on Windows now returns True from :func:`~os.path.exists` -and a valid result from :func:`os.stat` with ``S_IFCHR`` set. diff --git a/Misc/NEWS.d/next/Windows/2019-08-22-09-04-44.bpo-37549.TpKI3M.rs= t b/Misc/NEWS.d/next/Windows/2019-08-22-09-04-44.bpo-37549.TpKI3M.rst deleted file mode 100644 index 5345da80781d9..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-22-09-04-44.bpo-37549.TpKI3M.rst +++ /dev/null @@ -1 +0,0 @@ -:func:`os.dup` no longer fails for standard streams on Windows 7. diff --git a/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rs= t b/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst deleted file mode 100644 index a374c3a2965a6..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst +++ /dev/null @@ -1 +0,0 @@ -Improve the implementation of ``winerror_to_errno()``. diff --git a/Misc/NEWS.d/next/Windows/2019-09-03-11-47-37.bpo-38020.xFZ2j0.rs= t b/Misc/NEWS.d/next/Windows/2019-09-03-11-47-37.bpo-38020.xFZ2j0.rst deleted file mode 100644 index e6ddaba2f67b0..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-03-11-47-37.bpo-38020.xFZ2j0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes potential crash when calling :func:`os.readlink` (or indirectly -through :func:`~os.path.realpath`) on a file that is not a supported link. diff --git a/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rs= t b/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst deleted file mode 100644 index f1be8a1e1c86f..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-04-14-01-08.bpo-38030._USdtk.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes :func:`os.stat` failing for block devices on Windows diff --git a/Misc/NEWS.d/next/Windows/2019-09-09-12-22-23.bpo-37283.8NvOkU.rs= t b/Misc/NEWS.d/next/Windows/2019-09-09-12-22-23.bpo-37283.8NvOkU.rst deleted file mode 100644 index 973047839301e..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-09-12-22-23.bpo-37283.8NvOkU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure command-line and unattend.xml setting override previously detected -states in Windows installer. diff --git a/Misc/NEWS.d/next/Windows/2019-09-10-14-17-25.bpo-38088.FOvWSM.rs= t b/Misc/NEWS.d/next/Windows/2019-09-10-14-17-25.bpo-38088.FOvWSM.rst deleted file mode 100644 index 37bdeeadd894a..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-10-14-17-25.bpo-38088.FOvWSM.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes distutils not finding vcruntime140.dll with only the v142 toolset -installed. diff --git a/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rs= t b/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst deleted file mode 100644 index ca625cc775a20..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-10-14-21-40.bpo-38087.--eIib.rst +++ /dev/null @@ -1 +0,0 @@ -Fix case sensitivity in test_pathlib and test_ntpath. diff --git a/Misc/NEWS.d/next/Windows/2019-09-11-10-22-01.bpo-38081.8JhzjD.rs= t b/Misc/NEWS.d/next/Windows/2019-09-11-10-22-01.bpo-38081.8JhzjD.rst deleted file mode 100644 index e9d7a30eed9f9..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-11-10-22-01.bpo-38081.8JhzjD.rst +++ /dev/null @@ -1 +0,0 @@ -Prevent error calling :func:`os.path.realpath` on ``'NUL'``. diff --git a/Misc/NEWS.d/next/Windows/2019-09-11-12-34-31.bpo-36634.xLaGgb.rs= t b/Misc/NEWS.d/next/Windows/2019-09-11-12-34-31.bpo-36634.xLaGgb.rst deleted file mode 100644 index c0bd2beaae2df..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-11-12-34-31.bpo-36634.xLaGgb.rst +++ /dev/null @@ -1,2 +0,0 @@ -venv activate.bat now works when the existing variables contain double quote -characters. diff --git a/Misc/NEWS.d/next/Windows/2019-09-11-14-42-04.bpo-36634.8Un8ih.rs= t b/Misc/NEWS.d/next/Windows/2019-09-11-14-42-04.bpo-36634.8Un8ih.rst deleted file mode 100644 index 1affdd81cbfac..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-11-14-42-04.bpo-36634.8Un8ih.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`os.cpu_count` now returns active processors rather than maximum -processors. diff --git a/Misc/NEWS.d/next/Windows/2019-09-11-14-51-56.bpo-32592.jvQMD9.rs= t b/Misc/NEWS.d/next/Windows/2019-09-11-14-51-56.bpo-32592.jvQMD9.rst deleted file mode 100644 index c07a1213308e8..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-11-14-51-56.bpo-32592.jvQMD9.rst +++ /dev/null @@ -1 +0,0 @@ -Set Windows 8 as the minimum required version for API support diff --git a/Misc/NEWS.d/next/Windows/2019-09-11-15-24-04.bpo-38114.cc0E5E.rs= t b/Misc/NEWS.d/next/Windows/2019-09-11-15-24-04.bpo-38114.cc0E5E.rst deleted file mode 100644 index 5dab8d728e881..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-11-15-24-04.bpo-38114.cc0E5E.rst +++ /dev/null @@ -1 +0,0 @@ -The ``pip.ini`` is no longer included in the Nuget package. diff --git a/Misc/NEWS.d/next/Windows/2019-09-12-12-05-55.bpo-38133.yFeRGS.rs= t b/Misc/NEWS.d/next/Windows/2019-09-12-12-05-55.bpo-38133.yFeRGS.rst deleted file mode 100644 index 3fbf01693d550..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-12-12-05-55.bpo-38133.yFeRGS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow py.exe launcher to locate installations from the Microsoft Store and -improve display of active virtual environments. diff --git a/Misc/NEWS.d/next/Windows/2019-09-13-14-11-42.bpo-38092.x31ehI.rs= t b/Misc/NEWS.d/next/Windows/2019-09-13-14-11-42.bpo-38092.x31ehI.rst deleted file mode 100644 index 48e83c8d15672..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-13-14-11-42.bpo-38092.x31ehI.rst +++ /dev/null @@ -1 +0,0 @@ -Reduce overhead when using multiprocessing in a Windows virtual environment. diff --git a/Misc/NEWS.d/next/Windows/2019-09-16-14-07-11.bpo-38117.hJVf0C.rs= t b/Misc/NEWS.d/next/Windows/2019-09-16-14-07-11.bpo-38117.hJVf0C.rst deleted file mode 100644 index 4fd8a66d279e9..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-09-16-14-07-11.bpo-38117.hJVf0C.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled OpenSSL to 1.1.1d diff --git a/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rs= t b/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst deleted file mode 100644 index 56e0f56505522..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-02-15-38-49.bpo-38355.n3AWX6.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes ``ntpath.realpath`` failing on ``sys.executable``. diff --git a/Misc/NEWS.d/next/Windows/2019-10-03-08-04-14.bpo-38359.wzwsl_.rs= t b/Misc/NEWS.d/next/Windows/2019-10-03-08-04-14.bpo-38359.wzwsl_.rst deleted file mode 100644 index ab6f29baf5358..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-03-08-04-14.bpo-38359.wzwsl_.rst +++ /dev/null @@ -1 +0,0 @@ -Ensures ``pyw.exe`` launcher reads correct registry key. diff --git a/Misc/NEWS.d/next/Windows/2019-10-05-05-50-58.bpo-38344.scr2LO.rs= t b/Misc/NEWS.d/next/Windows/2019-10-05-05-50-58.bpo-38344.scr2LO.rst deleted file mode 100644 index b5854d1ecb0d3..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-05-05-50-58.bpo-38344.scr2LO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix error message in activate.bat diff --git a/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rs= t b/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst deleted file mode 100644 index 41fe695413f97..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-16-09-49-09.bpo-38492.Te1LxC.rst +++ /dev/null @@ -1 +0,0 @@ -Remove ``pythonw.exe`` dependency on the Microsoft C++ runtime. diff --git a/Misc/NEWS.d/next/Windows/2019-10-28-05-01-29.bpo-38519.dCkY66.rs= t b/Misc/NEWS.d/next/Windows/2019-10-28-05-01-29.bpo-38519.dCkY66.rst deleted file mode 100644 index 56d8bb2b34c10..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-28-05-01-29.bpo-38519.dCkY66.rst +++ /dev/null @@ -1,2 +0,0 @@ -Restores the internal C headers that were missing from the nuget.org and -Microsoft Store packages. diff --git a/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rs= t b/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst deleted file mode 100644 index deacb03c6f01d..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-28-10-32-43.bpo-38453.NwwatW.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure ntpath.realpath() correctly resolves relative paths. diff --git a/Misc/NEWS.d/next/Windows/2019-10-28-10-48-16.bpo-38589.V69Q1a.rs= t b/Misc/NEWS.d/next/Windows/2019-10-28-10-48-16.bpo-38589.V69Q1a.rst deleted file mode 100644 index e864290723e07..0000000000000 --- a/Misc/NEWS.d/next/Windows/2019-10-28-10-48-16.bpo-38589.V69Q1a.rst +++ /dev/null @@ -1 +0,0 @@ -Fixes HTML Help shortcut when Windows is not installed to C drive diff --git a/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst = b/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst deleted file mode 100644 index 164950a37c838..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-06-18-00-30-40.bpo-34631.vSifcv.rst +++ /dev/null @@ -1 +0,0 @@ -Updated OpenSSL to 1.1.1c in macOS installer. diff --git a/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst = b/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst deleted file mode 100644 index 5e05ac56b0956..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-06-18-08-58-30.bpo-35360.-CWbfy.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to use SQLite 3.28.0. diff --git a/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst = b/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst deleted file mode 100644 index c50ac638df577..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-07-02-01-06-47.bpo-34602.10d4wl.rst +++ /dev/null @@ -1,4 +0,0 @@ -Avoid test suite failures on macOS by no longer calling resource.setrlimit -to increase the process stack size limit at runtime. The runtime change is -no longer needed since the interpreter is being built with a larger default -stack size. diff --git a/Misc/NEWS.d/next/macOS/2019-07-13-15-58-18.bpo-18049.MklhQQ.rst = b/Misc/NEWS.d/next/macOS/2019-07-13-15-58-18.bpo-18049.MklhQQ.rst deleted file mode 100644 index 5af07cdb4119f..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-07-13-15-58-18.bpo-18049.MklhQQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Increase the default stack size of threads from 5MB to 16MB on macOS, to -match the stack size of the main thread. This avoids crashes on deep recursi= on -in threads. diff --git a/Misc/NEWS.d/next/macOS/2019-09-10-14-24-35.bpo-38089.eedgyD.rst = b/Misc/NEWS.d/next/macOS/2019-09-10-14-24-35.bpo-38089.eedgyD.rst deleted file mode 100644 index 41349848621ec..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-09-10-14-24-35.bpo-38089.eedgyD.rst +++ /dev/null @@ -1 +0,0 @@ -Move Azure Pipelines to latest VM versions and make macOS tests optional diff --git a/Misc/NEWS.d/next/macOS/2019-09-15-21-29-13.bpo-38117.ZLsoAZ.rst = b/Misc/NEWS.d/next/macOS/2019-09-15-21-29-13.bpo-38117.ZLsoAZ.rst deleted file mode 100644 index 644f147c95535..0000000000000 --- a/Misc/NEWS.d/next/macOS/2019-09-15-21-29-13.bpo-38117.ZLsoAZ.rst +++ /dev/null @@ -1 +0,0 @@ -Updated OpenSSL to 1.1.1d in macOS installer. diff --git a/README.rst b/README.rst index dfc8566d5ec40..62dd0fd4e9450 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.9.0 alpha 0 +This is Python version 3.9.0 alpha 1 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 .. image:: https://travis-ci.org/python/cpython.svg?branch=3Dmaster